[英]R data.table: How do you create a new column with a name from a string?
[英]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 有列col1
、 col2
、 col3
、 col4
、 col5
、 coln
。
要刪除其中的一個子集:
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.