R 通过字符串访问data.table字段的函数;或者,如何模拟lm中的数据

R 通过字符串访问data.table字段的函数;或者,如何模拟lm中的数据,r,data.table,R,Data.table,我试图构建一个由数据.table字段派生的变量矩阵 具体来说,假设我有一个data.tabledt和变量x1,x2,x3,我想用列x1,log(x1),as.numeric(as.factor(x3))和3*x2-x1制作nrow(dt)x4矩阵 一次过的解决办法是打电话 cbind(dt$x1, log(dt$x1), as.numeric(as.factor(data$x3)), 3 * data$x2-data$x1) 但我想要更具延展性的东西——我稍后会用这个矩阵做一些其他的事情 当指

我试图构建一个由
数据.table
字段派生的变量矩阵

具体来说,假设我有一个data.table
dt
和变量
x1
x2
x3
,我想用列
x1
log(x1)
as.numeric(as.factor(x3))
3*x2-x1
制作
nrow(dt)
x4矩阵

一次过的解决办法是打电话

cbind(dt$x1, log(dt$x1), as.numeric(as.factor(data$x3)), 3 * data$x2-data$x1)
但我想要更具延展性的东西——我稍后会用这个矩阵做一些其他的事情

当指定
data=
参数时,我想这样做与
lm
一样徒劳,在这里我可以从字符串列表中提取变量来执行回归——例如,如果我有
var\u名称
(包括变量的函数,例如
“log(x1)”
“as.factor(x2)”
),我可以调用
lm(y~as.formula)(粘贴(var_names[5:8],collapse=“+”),data=dt)
,它将正确执行

由于应用于变量的函数,我的第一本能——使用
[[
——不起作用:

dt[["log(x1)"]] = NULL
更有希望的是在
j
中进行评估,但我也无法实现这一点:

dt[ , log(x1)] # is fine, but I don't know how to access this from "log(x1)"
dt[ , "log(x1)"] = "log(x1)" #whomp
dt[ , get("log(x1)")] #Error--looking for object named log(x1), as with [[
dt[ , as.formula("log(x1)")] #getting warmer--looks for x1 in the global environment
我不确定如何为
dt
指定环境;我试图了解为
lm
调用
data=
是如何工作的,但没有取得任何进展

但是如果
dt
的环境是
envdt
,我认为这会起作用:

dt[ , as.formula("log(x1)", env = envdt)]
如果我能做到这一点,我将循环通过字符向量得到我的矩阵:

mat <- c()
for (vv in var_names){
   mat <- cbind(mat, dt[ , as.formula(vv, env = envdt)])
}

mat这里有一个选项,它使用
.SD
作为计算表达式的环境。
.SD
表示当前
数据。table
(或者至少是当前子组减去分组变量,但由于我们没有分组,所以它与整个表相同):


数据表有点像使用
,例如查看
dt[,environment()]
。请注意,它不返回全局env。但就目前情况而言,您的问题是不可复制的。请提供一些数据,以便我们可以做您正在做的事情!您能详细说明为什么这样做,但
dt[,as.formula(“log(x1)”,env=.SD)]
没有?另外,这是如何工作的,以及
lm
如何实现
数据=
参数之间是否有明确的联系?@MichaelChirico,我不太熟悉
as.formula
,但它似乎不会做你认为它应该做的事情(即生成一个表达式进行计算).as.formula
as.formula
创建公式,前提是您提供的字符串包含一个
~
。公式接近引用调用,这正是您所需要的。
quote
expression
都会生成引用调用。除此之外,您还需要对调用求值。
data.table
不会自动执行此操作在上面的示例中,我们使用
lappy
eval
应用于
调用
表达式的每个成员。作为将来的参考,我还发现在我所做的工作中,知道我可以通过
解析(text=char\u vec)从字符向量到表达式对象非常有用
char\u vec
转换为表达式,然后我们可以使用布罗迪的方法,例如
sapply(parse(text=char\u vec),eval)
dt <- data.table(x1=1:10, x2=1:10, x3=1:10)
calls <- expression(x1, log(x1), as.numeric(as.factor(x3)), 3 * x2 - x1)
mx <- as.matrix(dt[, lapply(calls, eval, envir=.SD)])   # <- note `.SD`

colnames(mx) <- sapply(calls, deparse, width=500)       # Make pretty 
mx
      x1   log(x1) as.numeric(as.factor(x3)) 3 * x2 - x1
 [1,]  1 0.0000000                         1           2
 [2,]  2 0.6931472                         2           4
 [3,]  3 1.0986123                         3           6
 [4,]  4 1.3862944                         4           8
 [5,]  5 1.6094379                         5          10
 [6,]  6 1.7917595                         6          12
 [7,]  7 1.9459101                         7          14
 [8,]  8 2.0794415                         8          16
 [9,]  9 2.1972246                         9          18
[10,] 10 2.3025851                        10          20