我知道我应该避免for循环,但我不确定如何使用apply函数做我想做的事情。
这是我正在尝试做的略微简化的模型。所以,基本上我有一个很大的预测变量矩阵,我想在索引预测器的每一侧使用一个包含5个预测变量的窗口运行回归(在for循环的情况下)。有了for循环,我可以说:
results<-NULL
window<-5
for(i in 1:ncol(g))
{
first<-i-window #Set window boundaries
if(first<1){
1->first
}
last<-i+window-1
if(last>ncol(g)){
ncol(g)->last
}
predictors<-g[,first:last]
#Do regression stuff and return some result
results[i]<-regression stuff
}
使用apply函数有一个好方法吗?我的问题是,应用的向量将推入函数真的无所谓。重要的是指数。
答案 0 :(得分:9)
这个问题涉及“The R Inferno”http://www.burns-stat.com/pages/Tutor/R_inferno.pdf
中提出的几点你应该避免一些循环,但不是全部。并且使用apply函数比隐藏循环更隐藏循环。这个例子似乎是留在'for'循环中的好选择。
增长对象通常是不好的形式 - 在某些情况下它可能效率极低。如果你想要一个统一的规则,那么“不增长对象”比“避免循环”更好。
您可以通过以下方式创建最终长度的列表:
result <- vector("list", ncol(g))
for(i in 1:ncol(g)) {
# stuff
result[[i]] <- #results
}
在某些情况下,您可能会想到命令:
window<-5
表示给我一个逻辑向量,说明'window'的哪些值小于-5。
空间很好用,大多数不是为了混淆人类,而是直接得到上面的含义而不是混淆R.
答案 1 :(得分:4)
在这种情况下,使用apply
函数进行回归主要是偏好问题;它可以为你处理一些簿记(因此可能会防止错误),但不会加速代码。
我建议使用矢量化函数来计算你的first
和last
,但是,或许类似于:
window <- 5
ng <- 15 #or ncol(g)
xy <- data.frame(first = pmax( (1:ng) - window, 1 ),
last = pmin( (1:ng) + window, ng) )
或者用
更聪明xy <- data.frame(first= c(rep(1, window), 1:(ng-window) ),
last = c((window+1):ng, rep(ng, window)) )
然后你可以在这样的for
循环中使用它:
results <- list()
for(i in 1:nrow(xy)) {
results[[i]] <- xy$first[i] : xy$last[i]
}
results
或lapply
就像这样:
results <- lapply(1:nrow(xy), function(i) {
xy$first[i] : xy$last[i]
})
在这两种情况下,我只返回first和list之间的序列;你会用你的实际回归代码替换。