如何将列列表传递给data.table,其中一些是预定的

时间:2014-06-17 23:18:42

标签: r data.table

将字符向量和列名称作为列列表传递给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正在寻找的环境,但我无法弄清楚我到底做错了什么。另外,如何保留列标题?

3 个答案:

答案 0 :(得分:2)

尝试在一次通话中混合标准和非标准评估可能会以眼泪/沮丧/晦涩的代码结束。

data.table

中有很多选项
  1. 使用字符向量和with=FALSE

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

    z[, .SD, .SDcols = cols]
    
  3. 但是如果你真的想要结合两种引用方式,那么你可以使用像

    这样的东西
    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
    

答案 1 :(得分:2)

这里有两个(非常相同)选项。一个使用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会返回命名清单。

答案 2 :(得分:1)

将变量与列名与data.table

中的硬编码列名组合在一起

从上例中给出zcols

要将变量col中的列名列表与其他硬编码列名c合并,我们会在调用{{1}的新字符向量c(col, 'c')中将它们合并}}。然后我们将参数data.table传递给with=FALSE

data.table

z[, c(cols, 'c'), with=FALSE] 参数告诉with=FALSE使用新向量作为名称向量来从data.table中进行选择。默认值data.table会将它们视为变量。因此,调用with=TRUE会返回包含z[, c(cols, 'c')]中元素的字符向量,即:c(cols, 'c')

感谢@thelatemail为上述解决方案提供基础。