簡體   English   中英

如何在data.table中按名稱刪除列?

[英]How do you delete a column by name in data.table?

要擺脫data.frame名為“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對象,這將不再有效。

以下任何一項都會從 data.table df3刪除列foo

# 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"]  

但是,如果您確實想從df3刪除列"foo" (而不是僅打印df3減去列"foo"的視圖),則您確實想改用方法 1。

(請注意,如果您使用依賴於grep()grepl() ,則需要設置pattern="^foo$"而不是"foo" ,如果您不想要名稱如"fool""buffoon" (即包含foo作為子字符串的那些)也將被匹配和刪除。)

不太安全的選項,適合交互式使用:

接下來的兩個習語也將起作用——如果df3包含一個匹配"foo"的列——但如果它不存在,則可能會以意想不到的方式失敗。 例如,如果您使用它們中的任何一個來搜索不存在的列"bar" ,您最終會得到一個零行的 data.table。

因此,它們真的最適合交互式使用,例如,人們可能想要顯示一個 data.table 減去名稱包含子字符串"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]

您也可以為此使用set ,這樣可以避免循環中[.data.table的開銷:

dt <- data.table( a=letters, b=LETTERS, c=seq(26), d=letters, e=letters )
set( dt, j=c(1L,3L,5L), value=NULL )
> dt[1:5]
   b d
1: A a
2: B b
3: C c
4: D d
5: E e

如果您想按列名進行操作, which(colnames(dt) %in% c("a","c","e"))應該適用於j

我只是用數據框的方式來做:

DT$col = NULL

工作速度很快,據我所知不會造成任何問題。

更新:如果您的 DT 非常大,則不是最好的方法,因為使用$<-運算符將導致對象復制。 所以更好地使用:

DT[, col:=NULL]

非常簡單的選項,以防您在數據表中有許多單獨的列要刪除,並且您想避免輸入所有列名 #careadviced

dt <- dt[, -c(1,4,6,17,83,104)]

這將根據列號刪除列。

它顯然沒有那么高效,因為它繞過了 data.table 的優勢,但如果您使用的行數少於 500,000 行,它就可以正常工作

假設您的 dt 有列col1col2col3col4col5coln

要刪除其中的一個子集:

vx <- as.character(bquote(c(col1, col2, col3, coln)))[-1]
DT[, paste0(vx):=NULL]

這是一種方法,當您想將列數設置為 NULL 時,考慮到列名是您使用的函數:)

deleteColsFromDataTable <- function (train, toDeleteColNames) {

       for (myNm in toDeleteColNames)

       train <- train [,(myNm):=NULL]

       return (train)
}
DT[,c:=NULL] # remove column c

對於 data.table,將列分配給 NULL 會將其刪除:

DT[,c("col1", "col1", "col2", "col2")] <- NULL
^
|---- Notice the extra comma if DT is a data.table

...相當於:

DT$col1 <- NULL
DT$col2 <- NULL
DT$col3 <- NULL
DT$col4 <- NULL

data.frame 的等效項是:

DF[c("col1", "col1", "col2", "col2")] <- NULL
      ^
      |---- Notice the missing comma if DF is a data.frame

Q. 為什么data.table的版本有逗號,data.frame的版本沒有逗號?

A. 由於 data.frames 存儲為列列表,您可以跳過逗號。 您也可以添加它,但是您需要將它們分配給NULL s、 DF[, c("col1", "col2", "col3")] <- list(NULL)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM