【问题标题】:How to pass a list of columns to data.table where some are predetermined如何将列列表传递给预先确定的 data.table
【发布时间】:2014-06-17 23:18:41
【问题描述】:

将字符向量和列名作为列列表传递给data.table

我希望能够在 R 中使用 data.table 生成列的子集,这样我可以更早地确定其中的一些列并将预定列表作为字符向量传递,然后与静态列表相结合列。

也就是说,鉴于此:

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 正在查看哪些环境,但我无法弄清楚我到底做错了什么。另外,如何保留列标题?

【问题讨论】:

  • z[,c(cols,'c'),with=FALSE] 够吗?我猜这可能是重复的。
  • @thelatemail - 这在我的示例和我自己的代码中运行良好。 'with=FALSE' 很有趣。我不认为我理解在 x 的框架内评估 j (with=TRUE)和让 j 是要选择的名称或位置的向量(with=FALSE)之间的区别。我需要进一步研究以了解所有已给出的答案。

标签: r data.table


【解决方案1】:

这里有两个(几乎相同的)选项。一个使用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 返回一个命名列表。

【讨论】:

  • 这很适合我的例子。但是,由于某种原因,它似乎不适用于我正在使用的实际代码。可能是我的例子中的一个缺陷。 @mnel 的答案在这两种情况下都有效。奇怪 - 我会找出原因并进行编辑。
【解决方案2】:

尝试在单个调用中混合标准和非标准评估可能会以眼泪/挫败/混淆代码而告终。

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

【讨论】:

  • 这很好用。我不知道为什么它适用于我正在使用的示例和实际代码,而@eddi 的答案却没有。我会试着弄清楚。
【解决方案3】:

将变量与列名与 data.table 中的硬编码列名相结合

给定上面示例中的zcols

要将变量col 中的列名列表与其他硬编码的列名c 组合在一起,我们在对data.table 的调用中将它们组合到一个新的字符向量c(col, 'c') 中。我们可以在j[] 中的第二个参数)中使用“up-one-level”符号.. 引用cols

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2012-11-19
    相关资源
    最近更新 更多