data.table中的动态列名称

时间:2012-07-31 16:52:05

标签: r data.table

我正在尝试向我的data.table添加列,其中名称是动态的。另外,我需要在添加这些列时使用by参数。例如:

test_dtb <- data.table(a = sample(1:100, 100), b = sample(1:100, 100), id = rep(1:10,10))
cn <- parse(text = "blah")
test_dtb[ , eval(cn) := mean(a), by = id]

# Error in `[.data.table`(test_dtb, , `:=`(eval(cn), mean(a)), by = id) : 
#  LHS of := must be a single column name when with=TRUE. When with=FALSE the LHS may be a vector of column names or positions.

另一次尝试:

cn <- "blah"
test_dtb[ , cn := mean(a), by = id, with = FALSE]
# Error in `[.data.table`(test_dtb, , `:=`(cn, mean(a)), by = id, with = FALSE) : 'with' must be TRUE when 'by' or 'keyby' is provided

马修更新:

这现在适用于R-Forge的v1.8.3。感谢您的重点!
有关新示例,请参阅此类似问题:

Assign multiple columns using data.table, by group

3 个答案:

答案 0 :(得分:29)

data.table 1.9.4,你可以这样做:

## A parenthesized symbol, `(cn)`, gets evaluated to "blah" before `:=` is carried out
test_dtb[, (cn) := mean(a), by = id]
head(test_dtb, 4)
#     a  b id blah
# 1: 41 19  1 54.2
# 2:  4 99  2 50.0
# 3: 49 85  3 46.7
# 4: 61  4  4 57.1

请参阅?:=中的详细信息

  

DT[i, (colvector) := val]

     

[...] NOW PREFERRED [...]语法。 parens足以阻止LHS成为一个象征;与c(colvector)

相同

原始回答:

您处于正确的轨道上:构建要在[.data.table调用中进行评估的表达式是 data.table 执行此类操作的方法。更进一步,为什么不构造一个表达式来计算整个 j参数(而不仅仅是它的左侧)?

这样的事情可以解决问题:

## Your code so far
library(data.table)
test_dtb <- data.table(a=sample(1:100, 100),b=sample(1:100, 100),id=rep(1:10,10))
cn <- "blah"

## One solution
expr <- parse(text = paste0(cn, ":=mean(a)"))
test_dtb[,eval(expr), by=id]

## Checking the result
head(test_dtb, 4)
#     a  b id blah
# 1: 30 26  1 38.4
# 2: 83 82  2 47.4
# 3: 47 66  3 39.5
# 4: 87 23  4 65.2

答案 1 :(得分:17)

表达式可以用bquote构建。

cn <- "blah"
expr <- bquote(.(as.name(cn)):=mean(a))
test_dtb[,eval(expr), by=id]

答案 2 :(得分:1)

我相信setnames(DT, c(col.names))会产生可读性最高的代码