【发布时间】:2013-05-10 00:26:30
【问题描述】:
我需要从包含几百列的 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-like:
> 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,那么内存可能更重要。
【问题讨论】:
-
一个问题:你打算删除这个专栏是什么?我的意思是你打算如何处理生成的 data.table?
-
@Arun 让我问的特殊情况是,我在使用
:=创建时错误地命名了一个列并想删除它。但总是会出现转储一两列很方便的情况。 -
正如@mnel 解释的那样,如果您只想删除,您可以直接使用
:=运算符,如果您想在没有此列的情况下执行计算,那么您始终可以使用.SDcols。因此,您可以完全避免subset/with=FALSE解决方案。
标签: r data.table