2017-08-31 52 views
1

在我目前的项目中,我有大约820万行。如果特定列的值不为零,我想扫描所有行并应用某个函数。如何加速和如果循环R

counter=1 
for(i in 1:nrow(data)){ 
if(data[i,8]!=0){ 
totalclicks=sum(data$Clicks[counter:(i-1)]) 
test$Clicks[i]=totalclicks 
counter=i 
    } 
} 

在上面的代码,我在820万行搜索的特定列,如果值不为零,那么我将计算sum了值。问题是forif循环太慢了。 50K行需要1小时。我听说apply家族是替代这一点。下面的代码还需要很长时间:

sapply(1:nrow(data), function(x) 
if(data[x,8]!=0){ 
totalclicks=sum(data$Clicks[counter:(x-1)]) 
test$Clicks[x]=totalclicks 
counter=x 
}) 

[更新] 请考虑以下为样本数据集:

clicks revenue new_column (sum of previous clicks) 
    1  0  
    2  0 
    3  5  3 
    1  0 
    4  0 
    2  7  8 

我想上面的一种解决方案,其中我将通过所有行。如果遇到任何非零收入值,则会添加以前的所有点击次数值。

我错过了什么吗?请纠正我。

+3

这很可能在几秒钟之内,如果你使用完成适当的矢量化,而不是循环遍历每一行。如果您提供可重复的示例和预期输出,您将获得更好的帮助。 –

+0

@docendodiscimus:我已通过添加示例数据集更新了问题。 –

+0

10是如何计算的? –

回答

1

aggregate()功能,可用于区分你的长期数据帧成块并在每块进行操作,所以你可以在你的榜样应用它为:

data <- data.frame(Clicks=c(1,2,3,1,4,2), 
        Revenue=c(0,0,5,0,0,7), 
        new_column=NA) 

sub_totals <- aggregate(data$Clicks, list(cumsum(data$Revenue)), sum) 
data$new_column[data$Revenue != 0] <- head(sub_totals$x, -1) 
+0

让我通过它并通知你。感谢你的回答。 –

+0

感谢您的完美回答:) –