【发布时间】:2015-04-03 17:18:55
【问题描述】:
我有一个函数,它输入一个 data.frame 并输出它的残差版本,其中一些选定的变量作为预测器。
residuals.DF = function(data, resid.var, suffix="") {
lm_f = function(x) {
x = residuals(lm(data=data, formula= x ~ eval(parse(text=resid.var))))
}
resid = data.frame(apply(data,2,lm_f))
colnames(resid) = paste0(colnames(data),suffix)
return(resid)
}
set.seed(31233)
df = data.frame(Age = c(1,3,6,7,3,8,4,3,2,6),
Var1 = c(19,45,76,34,83,34,85,34,27,32),
Var2 = round(rnorm(10)*100))
df.res = residuals.DF(df, "Age", ".test")
df.res
Age.test Var1.test Var2.test
1 -1.696753e-17 -25.1351351 -90.20582
2 -1.318443e-19 -0.8108108 31.91892
3 -5.397735e-18 27.6756757 84.10603
4 -5.927747e-18 -15.1621622 -105.83160
5 -3.807699e-18 37.1891892 -57.08108
6 -6.457759e-18 -16.0000000 -25.76923
7 5.117344e-17 38.3513514 -65.01871
8 -3.807699e-18 -11.8108108 35.91892
9 -3.277687e-18 -17.9729730 97.85655
10 -5.397735e-18 -16.3243243 94.10603
这很好用,但是,在处理 lm() 的变量输入时,我经常需要使用 eval 解析组合,所以我决定编写一个包装函数:
#Wrapper function for convenience for evaluating strings
evalparse = function(string) {
eval(parse(text=string))
}
单独使用时效果很好,例如:
> evalparse("5+5")
[1] 10
但是,如果在上述函数中使用它,则会得到:
> df.res = residuals.DF(df, "Age", ".test")
Error in eval(expr, envir, enclos) : object 'Age' not found
我认为这是因为包装函数意味着字符串在其自己的环境中被评估,其中所选变量缺失。使用 eval 解析组合时不会发生这种情况,因为它随后会发生在不缺少所选变量的 lm() 环境中。
这个问题有什么巧妙的解决办法吗?在 lm() 中使用动态公式的更好方法?否则我将不得不继续输入 eval(parse(text=object))。
【问题讨论】:
-
你试过用
mget()代替eval(parse())吗? -
get() 在上面的例子中有效,mget() 没有(返回错误的类型列表)。
-
啊,是的,对不起,我的意思是
get()。您可以使用mget(),但您需要mget()[[1]]从列表中获取项目。如果get()适合您,我会将其作为答案而不是评论发布。 -
如果
x和y是数据框DF中两列的名称,那么这会在x上回归y(带有截距) :lm(DF[c(y, x)])不使用parse、eval、公式等。
标签: r