Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 在data.table中删除单个列的习惯用法_R_Data.table - Fatal编程技术网

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

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中删除一列

使用
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