2017-07-19 60 views
0

我想以高效的方式運行下面的循環,因爲我需要在數百萬行上執行此操作。 樣本數據快速有效地循環下面的代碼R

a <- data.frame(x1=rep(c('a','b','c','d'),5), 
       x2=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5), 
       value1=c(rep(201,4),rep(202,4),rep(203,4),rep(204,4),rep(205,4)), 
       y1=c(rep('a',4),rep('b',4),rep('c',4),rep('d',4),rep('e',4)), 
       y2=c(1,2,3,4,2,3,4,5,3,4,5,6,4,5,6,7,5,6,7,8), 
       value2=seq(101,120), stringsAsFactors = FALSE) 

我下面寫的兩列之間的比較相似的價值觀,然後找到的差異。

for (i in 1:length(a$x1)){ 
    for (j in 1:length(a$x1)){ 
    if(a$y1[i] == a$x1[j] & a$y2[i] == a$x2[j]){ 
     a$diff[i] <- a$value1[j] - a$value2[i] 
     break 
    } 
    } 
} 
+2

我有一些無法理解的期望輸出應該是什麼樣的,我懷疑你的for循環有問題。你可以編輯你的問題,以顯示在你的例子中輸出「差異」列應該是什麼樣子? –

+0

你確定你提供的例子是正確的嗎?例如當我= 15 – Wen

+0

我錯過了我現在編輯它的休息聲明。謝謝你指出。 – Lufy

回答

0

對於每一個我,你要找到第j個這樣a$y1[i] == a$x1[j] && a$y2[i] == a$x2[j](在你的代碼,有&而不是&&這顯然是錯誤的)。

如果a$x1a$x2a$y1a$y2是數字或字符數據沒有空格(如在你的例子),你可以使用

x12 = paste(a$x1, a$x2) 
y12 = paste(a$y1, a$y2) 

然後爲每個我,你要找到第j個這樣的那x12[i]==y12[j]

你這樣做match(x12, y12)

所以,你可以做這樣的事情:

x12 = paste(a$x1, a$x2) 
y12 = paste(a$y1, a$y2) 
m = match(x12, y12) 
for (i in seql(m)) 
    if (!is.na(m[i])) 
     a$diff[i] <- a$value1[m[i]] - a$value2[i] 

可以消除最後一個循環是這樣的:

x12 = paste(a$x1, a$x2) 
y12 = paste(a$y1, a$y2) 
m = match(x12, y12) 
good.i = which(!is.na(m)) 
a$diff[good.i] <- a$value1[m[good.i]] - a$value2[good.i]