这是我的问题(虚构数据,以便可重现):
set.seed(42)
df<-data.frame("x"=rnorm(1000),"y"=rnorm(1000),"z"=rnorm(1000))
df2<-data.frame("x"=rnorm(100),"y"=rnorm(100),"z"=rnorm(100))
breaks<-c(-1000,-0.68,-0.01315,0.664,1000)
divider<-cut(df$x,breaks)
divider2<-cut(df2$x,breaks)
subDF<-by(df,INDICES=divider,data.frame)
subDF2<-by(df2,INDICES=divider2,data.frame)
reg<-lapply(subDF,lm,formula=x~.)
pre<-lapply(1:4,function(x){predict(reg[[x]],subDF2[[x]])})
lapply(1:4,function(x){summary(reg[[x]])$r.squared})
上面的代码工作正常。我正在做的是:根据x
的值,我将df
拆分为4个数据框并对每个数据框运行回归,以便能够预测其他数据框的值数据集。数据帧的拆分是为了更好地预测,因为x
的范围对实际数据有很大的影响。
我要做的是为回归添加权重参数,以便更加重视最新数据。我的权重参数是:weights<-0.999^seq(250,1,by=-1)
如果有250个数据。如果种子为42且之前的中断,则所有4个维度均为250。
当我尝试reg<-lapply(subDF,lm,formula=x~.,weights=0.999^seq(250,1,by=-1))
时,我收到了这个错误:
Error in eval(expr, envir, enclos) :
..2 used in an incorrect context, no ... to look in
这很奇怪,因为lapply
有一个...
参数,此处用于formula
,但它不接受weights
。
所以我真的不知道如何添加这些权重。我应该在我的代码中纠正什么,或者我(几乎)完全改变它以便能够使用权重?
对于示例并且为了使它(可能)更容易,我剪切了断点,使得4个子集具有相同的维度,但理想情况下,即使4个子集不是相同的维度,答案也会起作用(所以例如,breaks<-c(-1000,-0.75,0,0.75,1000)
的休息时间
This帖子有相同的问题,但没有一个有效的解决方案,所以这对我没有帮助。
答案 0 :(得分:6)
不幸的是,您在R中亲身经历过,可以说是最糟糕的错误。所谓的非标准评估(NSE)错误。
在对代码进行一些挖掘之后,我认为我找到了罪魁祸首。让我们逐一采取措施:
首先让我们看一下traceback()
:
weights <- 0.999^seq(250,1,by=-1)
lapply(subDF, lm, formula=x~., weights=weights)
Error in eval(expr, envir, enclos) :
..2 used in an incorrect context, no ... to look in
> traceback()
8: eval(expr, envir, enclos)
7: eval(extras, data, env)
6: model.frame.default(formula = ..1, data = X[[1L]], weights = ..2,
drop.unused.levels = TRUE)
5: stats::model.frame(formula = ..1, data = X[[1L]], weights = ..2,
drop.unused.levels = TRUE)
4: eval(expr, envir, enclos)
3: eval(mf, parent.frame())
2: FUN(X[[1L]], ...)
1: lapply(subDF, lm, formula = x ~ ., weights = weights)
看起来问题发生在model.frame.default
内。所以,让我们来看看源代码。我不会发布完整的源代码,但是如果你在控制台中输入model.frame.default
,你会看到中间的某个地方:
extras <- substitute(list(...))
extranames <- names(extras[-1L])
extras <- eval(extras, data, env)
最后一行是失败的地方。第一行是所谓的NSE,由substitute
创建。 substitute
会创建所谓的expression
,即让我们在eval
内稍后说出要评估(即创建)的对象。正如您在eval
中看到的那样,extras
将在data
中进行评估,然后在env
中找不到。对于公式,它是正常的,因为它在数据中进行评估,x~.
将告诉eval
使用data
中的所有列。 weights
虽然不在data
中。因此,eval
会在env
中查找。但是什么是env
?
显然,env
是一个环境,在行中的model.frame.default
内创建:
env <- environment(formula$terms)
那么,这是什么意思?让我们看另一个例子:
xtest <- function(x) {
new_func <- function(x) {
env <- environment(x)
print(env)
}
new_func(x)
}
> xtest(x~z)
<environment: R_GlobalEnv>
在上面的函数中,我尝试用更少的行复制env
model.frame.default
中的environment(formula)
。如您所见,env
指向全球环境。
因此,..2
试图找到...
,即weights
中传递的第二个参数(即...
),但是没有{{1}在全局环境中,您遇到了错误。希望现在很清楚!
最好的解决方案和我要做的是使用@Heroka的答案来解决它(或者你可以从头开始重写整个model.frame.default
和lm
而不使用NSE,但我认为首先是更合理:))。
答案 1 :(得分:3)
我不知道为什么你得到了你所得到的错误(我认为....
- 论证是为了这个。但是,我发现了一个轻微的解决方法,这是否符合你的需要?我所做的是在lapply中创建一个匿名函数,它计算权重(取决于数据的维度)并返回一个模型。
reg2 <- lapply(subDF, function(chunk){
#calculate weights (!dependent on data ordering)
weights <- 0.999^seq(nrow(chunk),1,by=-1)
#fit model
fit <- lm(x~., data=chunk, weights=weights)
return(fit)
})