簡體   English   中英

如何將列列表傳遞給 data.table,其中一些是預先確定的

[英]How to pass a list of columns to data.table where some are predetermined

將字符向量和列名作為列列表傳遞給data.table

我希望能夠使用 data.table 在 R 中生成列的子集,以便我可以更早地確定其中一些列並將預定列表作為字符向量傳遞,然后與列的靜態列表組合。

也就是說,鑒於此:

a <- 1:4
b <- 5:8
c <- c('aa','bb','cc','dd')
e <- 1:4

z <- data.table(a,b,c,e)

我想做這個:

z[, list(a,b)]

產生這個輸出:

   a b
1: 1 5
2: 2 6
3: 3 7
4: 4 8

但我想以與此類似的某種方式進行(幾乎有效):

cols <- "b"
z[, list(get(cols), a)]

結果:請注意,它不會返回存儲在cols中的列的名稱

   V1 a
1:  5 1
2:  6 2
3:  7 3
4:  8 4

但我需要使用多個cols元素來完成(這不起作用):

cols <- c('a', 'b')
z[, list(mget(cols), c)]

以上產生以下錯誤:

Error: value for ‘a’ not found

我認為我的問題在於范圍界定以及mget正在查看哪些環境,但我無法弄清楚我到底做錯了什么。 另外,如何保留列標題?

嘗試在單個調用中混合標准和非標准評估可能會以流淚/沮喪/混淆代碼結束。

data.table中有許多選項

  1. 使用..表示法“查找一級”以查找列名稱的向量

    cols <- c('a','b') z[, ..cols]
  2. 使用.SDcols

     z[, .SD, .SDcols = cols]

但是如果你真的想結合這兩種引用方式,那么你可以使用類似的東西(引入另一個選項, with=FALSE ,它允許比簡單向量更通用的列名表達式)

ll <- function(char=NULL,uneval=NULL){ 
        Call <- match.call()
        cols <- lapply(Call$uneval,as.character)
         unlist(c(char,cols))}
z[, ll(cols,c), with=FALSE]
#    a b  c
# 1: 1 5 aa
# 2: 2 6 bb
# 3: 3 7 cc
# 4: 4 8 dd

z[, ll(char=cols), with=FALSE]
#    a b
# 1: 1 5
# 2: 2 6
# 3: 3 7
# 4: 4 8

z[, ll(uneval=c), with=FALSE]
#     c
# 1: aa
# 2: bb
# 3: cc
# 4: dd

這里有兩個(幾乎等價的)選項。 一種使用lapply

z[, c(lapply(cols, get), list(c))]
#   V1 V2 V3
#1:  1  5 aa
#2:  2  6 bb
#3:  3  7 cc
#4:  4  8 dd

還有一個使用mget

z[, c(mget(cols, inherits = TRUE), c = list(c))]
#   a b  c
#1: 1 5 aa
#2: 2 6 bb
#3: 3 7 cc
#4: 4 8 dd

請注意, get返回一個向量,該向量丟失了有關列名的信息(除了手動將其重新添加之外,您無能為力),而mget返回一個命名列表。

將帶有列名的變量與 data.table 中的硬編碼列名相結合

給定上例中的zcols

為了將變量col中的列名列表與其他硬編碼的列名c組合,我們在調用data.table將它們組合到一個新的字符向量c(col, 'c')中。 我們可以通過使用“上一級”符號..來引用j cols[]的第二個參數):

z[, c(..cols, 'c')]

感謝@thelatemail 為上述解決方案提供基礎。

暫無
暫無

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

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