2017-08-31 73 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

感謝您的完美回答:) –