小编典典

如何在 data.table 中按名称删除列?

all

要摆脱 a 中名为“foo”的列data.frame,我可以这样做:

df <- df[-grep('foo', colnames(df))]

但是,一旦df转换为data.table对象,就没有办法只删除一列。

例子:

df <- data.frame(id = 1:100, foo = rnorm(100))
df2 <- df[-grep('foo', colnames(df))] # works
df3 <- data.table(df)
df3[-grep('foo', colnames(df3))]

但是一旦它被转换为一个data.table对象,它就不再起作用了。


阅读 69

收藏
2022-06-10

共1个答案

小编典典

foo以下任何一项都会从 data.table中删除列df3

# Method 1 (and preferred as it takes 0.00s even on a 20GB data.table)
df3[,foo:=NULL]

df3[, c("foo","bar"):=NULL]  # remove two columns

myVar = "foo"
df3[, (myVar):=NULL]   # lookup myVar contents

# Method 2a -- A safe idiom for excluding (possibly multiple)
# columns matching a regex
df3[, grep("^foo$", colnames(df3)):=NULL]

# Method 2b -- An alternative to 2a, also "safe" in the sense described below
df3[, which(grepl("^foo$", colnames(df3))):=NULL]

data.table 还支持以下语法:

## Method 3 (could then assign to df3, 
df3[, !"foo"]

但是,如果您实际上想从中删除 column "foo"df3而不是仅打印df3minus column的视图"foo"),您确实想改用方法
1。

(请注意,如果您使用依赖于的方法grep()or
grepl(),则需要设置pattern="^foo$"而不是"foo",如果您不希望名称为"fool"and的列"buffoon"(即包含foo作为子字符串的列)也被匹配和删除。)

不太安全的选项,适合交互式使用:

接下来的两个习语也可以使用——
如果df3包含匹配的列"foo"——但如果不匹配,则会以一种可能出乎意料的方式失败。例如,如果您使用它们中的任何一个来搜索不存在的列"bar",您最终会得到一个零行的
data.table。

因此,它们确实最适合交互式使用,例如,希望显示一个 data.table 减去名称包含 substring
的任何列"foo"。出于编程目的(或者,如果您想实际删除列df3而不是从其副本中删除),方法 1、2a 和 2b 确实是最佳选择。

# Method 4:
df3[, .SD, .SDcols = !patterns("^foo$")]

最后,有一些方法使用with=FALSE,
虽然data.table逐渐不再使用这个参数,所以现在不鼓励在可以避免的地方使用它;在此处显示,以便您知道该选项是否存在,以防您确实需要它:

# Method 5a (like Method 3)
df3[, !"foo", with=FALSE] 
# Method 5b (like Method 4)
df3[, !grep("^foo$", names(df3)), with=FALSE]
# Method 5b (another like Method 4)
df3[, !grepl("^foo$", names(df3)), with=FALSE]
2022-06-10