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.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)
但我想要更具延展性的东西——我稍后会用这个矩阵做一些其他的事情
当指定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.formulaas.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