R包data.table使用简单的语法(Matt在回答中很好地强调了这一点)提供了data.table的快速排序和内存高效排序。从那时起,已经有了很多改进,并且有了一个新的函数setorder()。从v1.9.5+开始,setorder()也适用于data.frames。
首先,我们将创建一个足够大的数据集,并对其他答案中提到的不同方法进行基准测试,然后列出data.table的特性。
数据:
require(plyr)
require(doBy)
require(data.table)
require(dplyr)
require(taRifx)
set.seed(45L)
dat = data.frame(b = as.factor(sample(c("Hi", "Med", "Low"), 1e8, TRUE)),
x = sample(c("A", "D", "C"), 1e8, TRUE),
y = sample(100, 1e8, TRUE),
z = sample(5, 1e8, TRUE),
stringsAsFactors = FALSE)
基准:
报告的计时来自运行system.time(…)的这些函数,如下所示。时间列表如下(按最慢到最快的顺序)。
orderBy( ~ -z + b, data = dat) ## doBy
plyr::arrange(dat, desc(z), b) ## plyr
arrange(dat, desc(z), b) ## dplyr
sort(dat, f = ~ -z + b) ## taRifx
dat[with(dat, order(-z, b)), ] ## base R
# convert to data.table, by reference
setDT(dat)
dat[order(-z, b)] ## data.table, base R like syntax
setorder(dat, -z, b) ## data.table, using setorder()
## setorder() now also works with data.frames
# R-session memory usage (BEFORE) = ~2GB (size of 'dat')
# ------------------------------------------------------------
# Package function Time (s) Peak memory Memory used
# ------------------------------------------------------------
# doBy orderBy 409.7 6.7 GB 4.7 GB
# taRifx sort 400.8 6.7 GB 4.7 GB
# plyr arrange 318.8 5.6 GB 3.6 GB
# base R order 299.0 5.6 GB 3.6 GB
# dplyr arrange 62.7 4.2 GB 2.2 GB
# ------------------------------------------------------------
# data.table order 6.2 4.2 GB 2.2 GB
# data.table setorder 4.5 2.4 GB 0.4 GB
# ------------------------------------------------------------
data.table的DT[order(…)]语法比其他最快的方法(dplyr)快约10倍,同时消耗与dplyr相同的内存量。data.table的setorder()比其他最快的方法(dplyr)快了约14倍,只需要0.4GB的额外内存。dat现在按照我们要求的顺序(通过引用更新)。
数据表功能:
速度:
表的排序非常快,因为它实现了基数排序。语法DT[order(…)]在内部进行了优化,以使用data.table的快速排序。您可以继续使用熟悉的基本R语法,但可以加快处理速度(并且使用更少的内存)。
内存:
大多数时候,我们不需要重新排序后的原始data.frame或data.table。也就是说,我们通常将结果分配回同一个对象,例如:DF<-DF[订单(…)]问题是,这至少需要原始对象的两倍(2倍)内存。为了提高内存效率,data.table还提供了一个函数setorder()。setorder()通过引用(就地)重新排序data.tables,而无需创建任何其他副本。它只使用相当于一列大小的额外内存。
其他功能:
它支持整数、逻辑、数字、字符和偶数位64::integer64类型。请注意,factor、Date、POSIXct等.类下面都是带有附加属性的整数/数字类型,因此也受支持。在基R中,我们不能使用字符向量上的-按该列降序排序。相反,我们必须使用-xtfrm(.)。然而,在data.table中,我们可以只做dat[order(-x)]或setorder(dat,-x)。