R 在data.table中删除单个列的习惯用法
我需要从包含几百列的data.frame中删除一列 使用R 在data.table中删除单个列的习惯用法,r,data.table,R,Data.table,我需要从包含几百列的data.frame中删除一列 使用data.frame,我可以使用子集方便地执行此操作: > 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
data.frame
,我可以使用子集
方便地执行此操作:
> 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
但是,我必须构建这样一个列表,它很笨重
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
>dat微基准(子集(dat,select=c(-z)),dat[,列表(x,y)])
单位:毫秒
expr最小lq中值uq最大
1数据[,列表(x,y)]102.62826 167.86793 170.72847 199.89789 792.0207
2子集(dat,select=c(-z))33.26356 52.55311 53.53934 55.00347 180.8740
但实际上,如果
子集复制整个数据,则更重要的是内存。如果要永久删除列,请使用:=NULL
dat[, z := NULL]
如果要将列作为字符串删除,请使用()
强制将求值作为字符串,而不是作为字符名
toDrop <- c('z')
dat[, (toDrop) := NULL]
但是,data.table
检查j
参数,只获取您以任何方式使用的列。参见常见问题1.12
当您写入X[Y,sum(foo*bar)],data.table
自动检查j表达式以查看它使用的列
并且不尝试加载.SD
的所有数据(除非调用j
时有.SD
)
subset.data.table
正在处理调用并最终计算dat[,c('x','y'),其中=FALSE]
使用:=NULL应该基本上是即时的,但是veer t确实会永久删除该列。我认为这就是您要寻找的
dat[, !"z"]
这是一个关于你编辑的大量数据的基准
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[, !"z"] 53.49184 57.31756 62.15506 112.7063 398.0107 100
subset.data.table
与您的调用相同,因为它们执行相同的操作请参见getAnywhere('subset.data.table')
与subset
相比,我更喜欢这种语法,因为。我假设相同的参数可以扩展到数据。表@Arun是否愿意解释这是如何工作的?例如,为什么with
选项必须是FALSE
。也就是说,它将data.table的列视为变量。为了克服此默认设置并获得与data.frame中相同的行为,我们将设置为with=FALSE
。如果不是的话,DT[,“x”]
将返回“x”
,因为“x”
的计算结果是“x”
。可能值得一读,了解更多信息。一个问题:你打算放弃这个专栏吗?我的意思是,您将如何处理生成的数据.table?@Arun让我提出疑问的是,在使用:=
创建列时,我将列命名错误,并希望将其删除。但总是有人说转储一两列很方便。正如@mnel所解释的,如果您只想删除,可以直接使用:=
运算符,如果您想在没有此列的情况下执行计算,则可以始终使用.SDcols
。因此,您可以使用=FALSE解决方案来避免子集
/。。。。几周来我一直在想怎么做。这一小技巧值得自己去问答。
dat[, !"z"]
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[, !"z"] 53.49184 57.31756 62.15506 112.7063 398.0107 100