2011-10-03 80 views
3

我知道我应该避免for循环,但我不完全确定如何执行我想要对apply函数执行的操作。R:与apply()vs for循环混淆

这是我想要做的略微简化的模型。所以,基本上我有一个预测变量的大矩阵,并且我想要在索引预测变量的每一边使用一个包含5个预测变量的窗口进行回归(在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 
} 

是否有与应用功能做到这一点的好办法?我的问题是,应用向量将推入功能真的无所谓。重要的是索引。

+0

AFAIK的意思是'apply'家庭只是语法糖,它实际上并没有加快你的码。 –

+1

萨沙......不完全是真的..值得注意的是,拉普利有时可以有惊人的加速。此外,语法糖可以让你分解复杂的循环和函数,以便适用于需要它的组件。 – John

+0

对于那些感兴趣的人,[这](http://stackoverflow.com/q/2275896/324364)SO问题是这个问题的一个很好的参考。 – joran

回答

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))) 

,那么你可以

results <- list() 
for(i in 1:nrow(xy)) { 
    results[[i]] <- xy$first[i] : xy$last[i] 
} 
results 
:在 for循环这样的使用

lapply这样的:

results <- lapply(1:nrow(xy), function(i) { 
    xy$first[i] : xy$last[i] 
}) 

凡在这两种情况下我刚刚回到第一和列表之间的序列;你会用你的实际回归代码替代。

8

这个问题涉及的是在做一些点“将R地狱” 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 

手段给我一个合理的载体,指出“窗口的哪些值'小于-5。

空间是很好用,主要是不要混淆人类,但要获得正上方,不要混淆R.