R:与apply()vs for循环混淆

时间:2011-10-03 16:50:17

标签: r

我知道我应该避免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函数有一个好方法吗?我的问题是,应用的向量将推入函数真的无所谓。重要的是指数。

2 个答案:

答案 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函数进行回归主要是偏好问题;它可以为你处理一些簿记(因此可能会防止错误),但不会加速代码。

我建议使用矢量化函数来计算你的firstlast,但是,或许类似于:

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之间的序列;你会用你的实际回归代码替换。

相关问题