R-Data.table-在RHS操作中使用变量列名

R-Data.table-在RHS操作中使用变量列名,r,data.table,R,Data.table,如何在:=操作的RHS上使用变量列名?例如,给定这个data.table“dt”,我想创建两个新列“first_y”和“first_z”,其中包含给定列对“x”值的第一次观察 但是,如果“y”和“z”列名动态存储在变量中,我该如何做呢 cols <- c("y", "z") # This doesn't work dt[, (paste0("first_", cols)) := .(first(cols)), by = x] # Nor does this q <- quote(

如何在:=操作的RHS上使用变量列名?例如,给定这个data.table“dt”,我想创建两个新列“first_y”和“first_z”,其中包含给定列对“x”值的第一次观察

但是,如果“y”和“z”列名动态存储在变量中,我该如何做呢

cols <- c("y", "z")

# This doesn't work
dt[, (paste0("first_", cols)) := .(first(cols)), by = x]

# Nor does this
q <- quote(first(as.name(cols[1])))
p <- quote(first(as.name(cols[2])))
dt[, (paste0("first_", cols)) := .(eval(q), eval(p)), by = x]

cols我不熟悉
first
函数(尽管它看起来像是哈德利定义的)


对于这种情况,
.SDcols
答案很好,但您也可以使用
get

dt[, paste0("first_", cols) := lapply(cols, function(x) get(x)[1]), by = x]
dt
#       x y z first_y first_z
#1:   one a 1       a       1
#2:   one b 2       a       1
#3:   two c 3       c       3
#4:   two d 4       c       3
#5: three e 5       e       5
dt[, paste0("first_", cols) := setDT(mget(cols))[1], by = x]
另一种选择是矢量化版本-
mget

dt[, paste0("first_", cols) := lapply(cols, function(x) get(x)[1]), by = x]
dt
#       x y z first_y first_z
#1:   one a 1       a       1
#2:   one b 2       a       1
#3:   two c 3       c       3
#4:   two d 4       c       3
#5: three e 5       e       5
dt[, paste0("first_", cols) := setDT(mget(cols))[1], by = x]

这可能是一个解决方案,但根据此常见问题解答:,不建议使用:dt[,(paste0(“first_u”,cols)):=first(.SD[[cols]]),by=x]作为一个有趣的注意事项,这种方法很有效:
dt[,(paste0(“first_u”,cols)):=lappy(lappy(lappy(cols,As.name),eval),first),by=x]
但是在顶级envI get的上下文中进行评估
错误:找不到对象“first”
,您能更新您的问题以使其可复制吗?jangorecki:first是一个dplyr函数,我想他只需要在顶部有一个库(dplyr),或者将其包含在某个地方。但是由于没有一个解决方案使用它,这有点没有意义。我一直认为
lapply(.SD,function(x)x[1L])
看起来更自然(事实上这就是
head
所做的),但这基本上是一个品味问题
。SD[1]
就足够了吗?它还进行了内部优化(因此速度更快)。
dt[, paste0("first_", cols) := setDT(mget(cols))[1], by = x]