以编程方式将列名称传递给data.table

Ale*_*lex 11 r data.table

我希望能够编写一个data.table按组运行回归的函数,然后很好地组织结果.以下是我想要做的一个示例:

require(data.table)
dtb = data.table(y=1:10, x=10:1, z=sample(1:10), weights=1:10, thedate=1:2)
models = c("y ~ x", "y ~ z")

res = lapply(models, function(f) {dtb[,as.list(coef(lm(f, weights=weights, data=.SD))),by=thedate]})

#do more stuff with res
Run Code Online (Sandbox Code Playgroud)

我想将所有这些包装成一个函数,因为它#doe more stuff可能很长.我面临的问题是如何将各种名称传递给data.table?例如,如何传递列名weights?我怎么通过thedate?我想象一个看起来像这样的原型:

myfun = function(dtb, models, weights, dates)
Run Code Online (Sandbox Code Playgroud)

让我说清楚:将公式传递给我的函数不是问题.如果weights我想使用和描述日期的列名称thedate已知,那么我的函数可能看起来像这样:

 myfun = function(dtb, models) {
res = lapply(models, function(f) {dtb[,as.list(coef(lm(f, weights=weights, data=.SD))),by=thedate]})

 #do more stuff with res
 }
Run Code Online (Sandbox Code Playgroud)

但是,对应于thedate和对应的列名称weights是事先未知的.我想将它们传递给我的函数:

#this will not work
myfun = function(dtb, models, w, d) {
res = lapply(models, function(f) {dtb[,as.list(coef(lm(f, weights=w, data=.SD))),by=d]})

 #do more stuff with res
 }
Run Code Online (Sandbox Code Playgroud)

谢谢

mne*_*nel 5

这是一个依赖于长格式数据的解决方案(这对我来说更有意义,在这个cas中

library(reshape2)
dtlong <- data.table(melt(dtb, measure.var = c('x','z')))


foo <- function(f, d, by, w ){
  # get the name of the w argument (weights)
  w.char <- deparse(substitute(w))
  # convert `list(a,b)` to `c('a','b')`
  # obviously, this would have to change depending on how `by` was defined
  by <- unlist(lapply(as.list(as.list(match.call())[['by']])[-1], as.character))
  # create the call substituting the names as required
  .c <- substitute(as.list(coef(lm(f, data = .SD, weights = w), list(w = as.name(w.char)))))
  # actually perform the calculations
  d[,eval(.c), by = by]
}

foo(f= y~value, d= dtlong, by = list(variable, thedate), w = weights)

   variable thedate (Intercept)       value
1:        x       1   11.000000 -1.00000000
2:        x       2   11.000000 -1.00000000
3:        z       1    1.009595  0.89019190
4:        z       2    7.538462 -0.03846154
Run Code Online (Sandbox Code Playgroud)