用于在data.table中删除单个列的习惯用法

时间:2013-05-10 00:26:31

标签: r data.table

我需要从包含几百列的data.frame中删除一列。

使用data.frame,我会使用subset方便地执行此操作:

> dat <- data.table( data.frame(x=runif(10),y=rep(letters[1:5],2),z=runif(10)),key='y' )
> subset(dat,select=c(-z))
            x y
 1: 0.1969049 a
 2: 0.7916696 a
 3: 0.9095970 b
 4: 0.3529506 b
 5: 0.4923602 c
 6: 0.5993034 c
 7: 0.1559861 d
 8: 0.9929333 d
 9: 0.3980169 e
10: 0.1921226 e

显然这仍然有效,但似乎不是一个非常data.table的成语。我可以手动构建一个我想保留的列名列表,这似乎更多data.table - 如:

> dat[,list(x,y)]
            x y
 1: 0.1969049 a
 2: 0.7916696 a
 3: 0.9095970 b
 4: 0.3529506 b
 5: 0.4923602 c
 6: 0.5993034 c
 7: 0.1559861 d
 8: 0.9929333 d
 9: 0.3980169 e
10: 0.1921226 e

但是我必须构建一个笨重的列表。

subset是方便地删除一两列的正确方法,还是会导致性能下降?如果没有,那么更好的方法是什么?

修改

基准:

> dat <- data.table( data.frame(x=runif(10^7),y=rep(letters[1:10],10^6),z=runif(10^7)),key='y' )
> microbenchmark( subset(dat,select=c(-z)), dat[,list(x,y)] )
Unit: milliseconds
                         expr       min        lq    median        uq      max
1           dat[, list(x, y)] 102.62826 167.86793 170.72847 199.89789 792.0207
2 subset(dat, select = c(-z))  33.26356  52.55311  53.53934  55.00347 180.8740

但如果subset复制整个data.table,那么真正重要的是内存。

2 个答案:

答案 0 :(得分:9)

如果您想永久删除该列,请使用:= NULL

dat[, z := NULL]

如果要将列作为字符串删除,请使用()强制将评估作为字符串,而不是字符名称。

toDrop <- c('z')

dat[, (toDrop) := NULL]

如果您想限制.SD中列的可用性,可以传递.SDcols参数

dat[,lapply(.SD, somefunction) , .SDcols = setdiff(names(dat),'z')]

但是,data.table检查j参数,只获取您使用的列。见FAQ 1.12

  

当你写X [Y,sum(foo * bar)]时,data.table   自动检查j表达式以查看它使用的列。

并且不会尝试加载.SD的所有数据(除非您在.SD的电话中有j


subset.data.table正在处理调用并最终评估dat[, c('x','y'), with=FALSE]

使用:= NULL应该基本上是即时的,如果永久删除列。

答案 1 :(得分:1)

我认为这就是你要找的东西。

dat[, !c("z"), with = FALSE]

以下是编辑中大量数据的基准。

Unit: milliseconds
                         expr       min        lq    median       uq      max neval
  subset(dat, select = c(-z))  53.37435  56.82514  61.81279 100.3458 339.1400   100
            dat[, list(x, y)] 191.46678 354.39905 412.06421 451.3933 678.3981   100
 dat[, !c("z"), with = FALSE]  53.49184  57.31756  62.15506 112.7063 398.0107   100
相关问题