将data.table的参数提供为(1)字符串向量和(2)变量名

时间:2014-05-10 17:42:36

标签: r data.table

想象一下,您想在data.table上逐行应用函数。函数的参数对应于固定的data.table列以及动态生成的列名。

有没有办法在使用data.tables?

时提供固定和动态列名作为函数的参数

问题是:

  • 变量名和动态生成的字符串作为数据表上的函数的参数
  • 动态列名称字符串存储在带有>的向量中1个条目(get()将无效)
  • 动态列的值需要作为函数
  • 的向量提供

这说明了它:

library('data.table')
# Sample dataframe
D <- data.table(id=1:3, fix=1:3, dyn1=1:3, dyn2=1:3) #fixed and dynamic column names
setkey(D, id)
# Sample function
foo <-function(fix, dynvector){ rep(fix,length(dynvector)) %*% dynvector}
# It does not matter what this function does.

# The result when passing column names not dynamically
D[, "new" := foo(fix,c(dyn1,dyn2)), by=id]
#    id fix dyn1 dyn2 new
# 1:  1   1    1    1   2
# 2:  2   2    2    2   8
# 3:  3   3    3    3  18

我想摆脱c(dyn1,dyn2)。我需要从另一个向量中获取列名dyn1,dyn2,它将它们保存为字符串。

这是我走了多远:

# Now we try it dynamically
cn <-paste("dyn",1:2,sep="")   #vector holding column names "dyn1", "dyn2"

# Approaches that don't work
D[, "new" := foo(fix,c(cn)), by=id]            #wrong as using a mere string
D[, "new" := foo(fix,c(cn)), by=id, with=F]    #does not work
D[, "new" := foo(fix,c(get(cn))), by=id]       #uses only the first element "dyn1"
D[, "new" := foo(fix,c(mget(cn, .GlobalEnv, inherits=T))), by=id]       #does not work
D[, "new" := foo(fix,c(.SD)), by=id, .SDcols=cn]       #does not work

我认为mget()是解决方案,但我对范围界定的了解太少了。

谢谢! JBJ


更新:解决方案

基于BondedDust的回答

    D[, "new" := foo(fix,sapply(cn, function(x) {get(x)})), by=id]

1 个答案:

答案 0 :(得分:0)

我无法弄清楚你试图用矩阵乘法做什么,但这显示了如何用函数的变化和固定输入创建新变量:

D <- data.table(id=1:3, fix=1:3, dyn1=1:3, dyn2=1:3) 
setkey(id)

foo <-function(fix, dynvector){ fix* dynvector}
D[, paste("new",1:2,sep="_") := lapply( c(dyn1,dyn2), foo, fix=fix), by=id]
#----------
> D
   id fix dyn1 dyn2 new_1 new_2
1:  1   1    1    1     1     1
2:  2   2    2    2     4     4
3:  3   3    3    3     9     9

因此,您需要使用get列的字符值向量。这是对此问题的一些扩展:Why do I need to wrap `get` in a dummy function within a J `lapply` call?

> D <- data.table(id=1:3, fix=1:3, dyn1=1:3, dyn2=1:3) 
> setkey(D, id)
> id1 <- parse(text=cn)
> foo <-function( fix, dynvector){  fix*dynvector}
> D[, paste("new",1:2,sep="_") := lapply( sapply( cn, function(x) {get(x)}) , foo, fix=fix) ]
Warning message:
In `[.data.table`(D, , `:=`(paste("new", 1:2, sep = "_"), lapply(sapply(cn,  :
  Supplied 2 columns to be assigned a list (length 6) of values (4 unused)
> D
   id fix dyn1 dyn2 new_1 new_2
1:  1   1    1    1     1     2
2:  2   2    2    2     2     4
3:  3   3    3    3     3     6

您也可以使用create an expression from a function for data.table to eval中的方法。