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
正在寻找的环境,但我无法弄清楚我到底做错了什么。另外,如何保留列标题?
答案 0 :(得分:2)
尝试在一次通话中混合标准和非标准评估可能会以眼泪/沮丧/晦涩的代码结束。
data.table
使用字符向量和with=FALSE
cols <- c('a','b')
z[, cols, with=FALSE]
使用.SDcols
z[, .SD, .SDcols = cols]
但是如果你真的想要结合两种引用方式,那么你可以使用像
这样的东西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)
从上例中给出z
和cols
:
要将变量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为上述解决方案提供基础。