ddply错误? (将组内计算的 lm 残差添加回原始数据框)
ddply bug? (Adding lm residuals computed within groups back to the original data frame)
我有一个带有因子 (grpfactor) 的数据框。我的目标是在每个组内分别计算拟合 lm 模型的残差,并将它们存储在原始数据框中。
需要在运行时指定模型(即不能是固定字符串)。
我找到了 this answer
ddply(d,.(g1,g2),transform,z= predict(lm(y ~ x)))
它似乎适用于静态指定的公式,但如果我将代码放入函数中并使用字符串变量而不是字符串文字(常量),它就会失败——为什么??
d <- data.frame(x = rnorm(20),
y = rnorm(20),
g1 = c(rep('a', 10), rep('b', 10)),
g2 = rep(c(rep('c', 5), rep('d', 5)), 2))
myfunc = function(d) {
xx = "y ~ x"
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx))))
return(retval)
}
# This fails:
d.new = myfunc(d)
# With the error:
#Error: error in evaluating the argument 'object' in selecting a
#method for function 'predict': Error in as.formula(xx) : object 'xx' not
#found
# But this works, because it's not encased in a function:
xx = "y ~ x"
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx))))
#Now, with the variable "xx" defined two lines above this line,
#the following will actually work now:
d.new = myfunc(d)
#But if we do this, it will fail again:
rm(xx)
d.new = myfunc(d)
#ddply works inside a function, but only with a model specified
#as a literal string:
myfunc2 = function(d) {
retval = ddply(d,.(g1,g2),transform,z= predict(lm(formula=as.formula("y ~ x"))))
return(retval)
}
d.new2 = myfunc2(d)
顺便说一句,没有 as.formula,myfunc2 失败并显示错误:
#Error: error in evaluating the argument 'object' in selecting a method
#for function 'predict': Error in eval(expr, envir, enclos) : object 'y'
#not found
但是如果不在函数中,相同的代码在没有 as.formula 的情况下也能正常工作。
这是怎么回事?
编辑:好的,这就是真正疯狂的地方:这有效(不同之处在于,我在父环境中使用 <<- 定义模型)
myfunc3 = function(d) {
xx <<- "y ~ x"
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx))))
return(retval)
}
myfunc3(d)
你收到错误:
Error: object of type 'closure' is not subsettable
因为当ddply
尝试在全局环境之前在本地环境中解析t
。事实上,它找到了转置函数(闭包)t
而不是你的全局变量 t。
您只需要更改为其他 R 内置函数(t、c、..)。例如,这将起作用:
xx <- "y ~ x"
一个完整的例子:
d <- data.frame(x = rnorm(20),
y = rnorm(20),
g1 = c(rep('a', 10), rep('b', 10)),
g2 = rep(c(rep('c', 5), rep('d', 5)), 2))
xx <- "y ~ x"
ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx))))
# x y g1 g2 z
# 1 -0.2066509 -0.74159051 a c -0.21886198
# 2 -0.9801753 1.38958373 a c 0.62214098
# 3 -0.4626821 0.48195967 a c 0.05950415
# 4 1.2255134 -1.72809777 a c -1.77596158
# 5 -1.0922717 0.02898265 a c 0.74401621
# 6 -1.4379229 0.96377879 a d 0.18312800
我有一个带有因子 (grpfactor) 的数据框。我的目标是在每个组内分别计算拟合 lm 模型的残差,并将它们存储在原始数据框中。
需要在运行时指定模型(即不能是固定字符串)。
我找到了 this answer
ddply(d,.(g1,g2),transform,z= predict(lm(y ~ x)))
它似乎适用于静态指定的公式,但如果我将代码放入函数中并使用字符串变量而不是字符串文字(常量),它就会失败——为什么??
d <- data.frame(x = rnorm(20),
y = rnorm(20),
g1 = c(rep('a', 10), rep('b', 10)),
g2 = rep(c(rep('c', 5), rep('d', 5)), 2))
myfunc = function(d) {
xx = "y ~ x"
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx))))
return(retval)
}
# This fails:
d.new = myfunc(d)
# With the error:
#Error: error in evaluating the argument 'object' in selecting a
#method for function 'predict': Error in as.formula(xx) : object 'xx' not
#found
# But this works, because it's not encased in a function:
xx = "y ~ x"
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx))))
#Now, with the variable "xx" defined two lines above this line,
#the following will actually work now:
d.new = myfunc(d)
#But if we do this, it will fail again:
rm(xx)
d.new = myfunc(d)
#ddply works inside a function, but only with a model specified
#as a literal string:
myfunc2 = function(d) {
retval = ddply(d,.(g1,g2),transform,z= predict(lm(formula=as.formula("y ~ x"))))
return(retval)
}
d.new2 = myfunc2(d)
顺便说一句,没有 as.formula,myfunc2 失败并显示错误:
#Error: error in evaluating the argument 'object' in selecting a method
#for function 'predict': Error in eval(expr, envir, enclos) : object 'y'
#not found
但是如果不在函数中,相同的代码在没有 as.formula 的情况下也能正常工作。
这是怎么回事?
编辑:好的,这就是真正疯狂的地方:这有效(不同之处在于,我在父环境中使用 <<- 定义模型)
myfunc3 = function(d) {
xx <<- "y ~ x"
retval = ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx))))
return(retval)
}
myfunc3(d)
你收到错误:
Error: object of type 'closure' is not subsettable
因为当ddply
尝试在全局环境之前在本地环境中解析t
。事实上,它找到了转置函数(闭包)t
而不是你的全局变量 t。
您只需要更改为其他 R 内置函数(t、c、..)。例如,这将起作用:
xx <- "y ~ x"
一个完整的例子:
d <- data.frame(x = rnorm(20),
y = rnorm(20),
g1 = c(rep('a', 10), rep('b', 10)),
g2 = rep(c(rep('c', 5), rep('d', 5)), 2))
xx <- "y ~ x"
ddply(d,.(g1,g2),transform,z= predict(lm(as.formula(xx))))
# x y g1 g2 z
# 1 -0.2066509 -0.74159051 a c -0.21886198
# 2 -0.9801753 1.38958373 a c 0.62214098
# 3 -0.4626821 0.48195967 a c 0.05950415
# 4 1.2255134 -1.72809777 a c -1.77596158
# 5 -1.0922717 0.02898265 a c 0.74401621
# 6 -1.4379229 0.96377879 a d 0.18312800