【发布时间】:2017-01-07 23:05:09
【问题描述】:
我正在使用一个包含多个组 (+2 百万) 的模拟数据集,我想在其中计算每个组的观察总数和高于阈值(这里为 2)的观察数。
当我创建一个标志变量时,它似乎要快得多,尤其是对于dplyr,而对于data.table,它要快一点。
为什么会这样?在每种情况下它是如何在后台工作的?
查看下面的示例。
模拟数据集
# create an example dataset
set.seed(318)
N = 3000000 # number of rows
dt = data.frame(id = sample(1:5000000, N, replace = T),
value = runif(N, 0, 10))
使用 dplyr
library(dplyr)
# calculate summary variables for each group
t = proc.time()
dt2 = dt %>% group_by(id) %>% summarise(N = n(),
N2 = sum(value > 2))
proc.time() - t
# user system elapsed
# 51.70 0.06 52.11
# calculate summary variables for each group after creating a flag variable
t = proc.time()
dt2 = dt %>% mutate(flag = ifelse(value > 2, 1, 0)) %>%
group_by(id) %>% summarise(N = n(),
N2 = sum(flag))
proc.time() - t
# user system elapsed
# 3.40 0.16 3.55
使用 data.table
library(data.table)
# set as data table
dt2 = setDT(dt, key = "id")
# calculate summary variables for each group
t = proc.time()
dt3 = dt2[, .(N = .N,
N2 = sum(value > 2)), by = id]
proc.time() - t
# user system elapsed
# 1.93 0.00 1.94
# calculate summary variables for each group after creating a flag variable
t = proc.time()
dt3 = dt2[, flag := ifelse(value > 2, 1, 0)][, .(N = .N,
N2 = sum(flag)), by = id]
proc.time() - t
# user system elapsed
# 0.33 0.04 0.39
【问题讨论】:
-
对于
data.table:sum(var)和.N是gforce 优化的。但还没有sum(expr).. 添加verbose = TRUE并查看优化表达式的差异。我们将在未来更好地捕捉这些案例。 -
注意:你不再需要为分组/加入操作设置键了。如果你想键也可以。但你知道,没有必要。
-
在
data.table我怀疑不同之处在于 data.table 已经在第二个实例中排序,所以你没有计算在内。尝试将dt2 = setDT(dt, key = "id")放在每个实例上方。 -
@Arun 可能它还发挥作用,一种方法对所有行进行逻辑比较,而另一种方法通过分组进行?
-
仅使用逻辑比较 (
flag := value > 2) 将进一步提高速度。
标签: r data.table dplyr