【发布时间】:2020-02-17 13:13:02
【问题描述】:
有multiple ways 可以通过使用包含所需列名(with=FALSE、..、mget、...)的变量来选择 data.table 的列。
是否有共识(何时)使用?data.table-y 是否比其他人多一个?
我可以提出以下论点:
-
with=FALSE和..几乎同样快,而mget更慢 -
..不能“即时”选择连接的列名(EDIT:当前 CRAN 版本1.12.8绝对可以,我使用的是旧版本,但不能,所以这个论点是有缺陷的) -
mget()接近于get()的有用语法,这似乎是在 j 计算中使用变量名的唯一方法
到(1):
library(data.table)
library(microbenchmark)
a <- mtcars
setDT(a)
selected_cols <- names(a)[1:4]
microbenchmark(a[, mget(selected_cols)],
a[, selected_cols, with = FALSE],
a[, ..selected_cols],
a[, .SD, .SDcols = selected_cols])
#Unit: microseconds
# expr min lq mean median uq max neval cld
# a[, mget(selected_cols)] 468.483 495.6455 564.2953 504.0035 515.4980 4341.768 100 c
# a[, selected_cols, with = FALSE] 106.254 118.9385 141.0916 124.6670 130.1820 966.151 100 a
# a[, ..selected_cols] 112.532 123.1285 221.6683 129.9050 136.6115 2137.900 100 a
# a[, .SD, .SDcols = selected_cols] 277.536 287.6915 402.2265 293.1465 301.3990 5231.872 100 b
到(2):
b <- data.table(x = rnorm(1e6),
y = rnorm(1e6, mean = 2, sd = 4),
z = sample(LETTERS, 1e6, replace = TRUE))
selected_col <- "y"
microbenchmark(b[, mget(c("x", selected_col))],
b[, c("x", selected_col), with = FALSE],
b[, c("x", ..selected_col)])
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# b[, mget(c("x", selected_col))] 5.454126 7.160000 21.752385 7.771202 9.301334 147.2055 100 b
# b[, c("x", selected_col), with = FALSE] 2.520474 2.652773 7.764255 2.944302 4.430173 100.3247 100 a
# b[, c("x", ..selected_col)] 2.544475 2.724270 14.973681 4.038983 4.634615 218.6010 100 ab
到(3):
b[, sqrt(get(selected_col))][1:5]
# [1] NaN 1.3553462 0.7544402 1.5791845 1.1007728
b[, sqrt(..selected_col)]
# error
b[, sqrt(selected_col), with = FALSE]
# error
编辑:将 .SDcols 添加到 (1) 中的基准,b[, c("x", ..selected_col)] 到 (2)。
【问题讨论】:
-
为了完整起见,您可能需要包含
a[, .SD, .SDcols = selected_cols] -
在 (2) 中动态连接列可以使用:
b[, c("x", ..selected_col)] -
也可以在(3)方括号中使用:
b[, sqrt(.SD[[selected_col]])]或sqrt(b[[selected_col]]) -
您始终可以在语言上进行计算:
eval(substitute(b[, .(x, selected_col)], list(selected_col = as.name(selected_col)))) -
我不打算这样做,特别是。只是认为在帖子中添加时间可能是个好主意,因为我正在努力寻找支持某种方式的论点。
标签: r data.table