2016-11-11 85 views
0

所以我有2個數據幀,兩者具有相同的結構:求和值 - 執行時間

V1 V2 V3 V4 C 
0 1 1 0 -1 
0 0 1 0 -1 
2 0 0 0 1 
2 0 0 0 1 
1 0 0 0 1 
2 0 0 0 1 

的V1-V4列是整數類型,將C列是因子與2級。 數據幀有不同的大小,第一個有〜50000行,另一個有〜600000行。我寫簡單的函數,在此行中由元件的總和除以該行中的每個元素:

SimpleFunction <- function(dataset) { 
    progress.bar <- create_progress_bar("text") 
    progress.bar$init(nrow(dataset)) 
    for (i in 1:nrow(dataset)) { 
    row.sum <- sum(dataset[i,1:4]) 
    dataset[i,1] <- dataset[i,1]/row.sum 
    dataset[i,2] <- dataset[i,2]/row.sum 
    dataset[i,3] <- dataset[i,3]/row.sum 
    dataset[i,4] <- dataset[i,4]/row.sum 
    progress.bar$step() 
    } 
    return(dataset) 
} 

現在我用「system.time」測試了這個功能執行的時間,以及用於50000行的數據幀其大約是45秒,但對於600000行數據幀來說,它需要很長的時間(1%大約2分鐘,我用「plyr」包中的這個簡單進度條測量它)。現在我的問題是:爲什麼?唯一改變的是行數,數據幀的結構是相同的。它不應該是線性增長,就像50000 - 45秒,600000 - 540秒? 我可以簡單地分割大數據框,在每個片段上運行函數,然後將它們合併到一起,但我真的不明白爲什麼會發生這種情況。

回答

1

您不需要爲此R使用循環專門用於向量化計算。所有循環行都會增加處理時間。因此,你可以做到這一點和R將爲每一行的行之和:

row.sum <- rowSums(dataset[,1:4]) 
dataset[,1] <- dataset[,1]/row.sum 
dataset[,2] <- dataset[,2]/row.sum 
dataset[,3] <- dataset[,3]/row.sum 
dataset[,4] <- dataset[,4]/row.sum 
+0

row.sum < - sum(dataset [,1:4])不返回每行中元素總和的向量 - 它返回標量爲1:4的所有元素的總和。 –

+0

對不起,你需要使用'rowSums(dataset [,1:4])''。你絕對不需要使用循環。 – MorganBall

+0

它適用於row.sum < - rowSums(dataset [,1:4])tho,並解決了我的問題 - 謝謝。 –

1

sweep在這裏有用的,如果你想要一個在線解決方案:

> dataset[, 1:4] <- sweep(dataset[,-5], 1, rowSums(dataset[,-5]), FUN="/") 
> dataset 
    V1 V2 V3 V4 C 
1 0 0.5 0.5 0 -1 
2 0 0.0 1.0 0 -1 
3 1 0.0 0.0 0 1 
4 1 0.0 0.0 0 1 
5 1 0.0 0.0 0 1 
6 1 0.0 0.0 0 1 

apply也適用:

dataset[, -5] <- apply(dataset[,-5], 2, function(x) x/rowSums(dataset[,-5]))