2013-01-10 56 views
7

這是一個玩具的例子,我最終總是寫一個循環。我無法搞清楚這一個班輪。我確信我已經看到它,但它並沒有堅持下去。在lapply中分配值

smallFrame <- data.frame(colA = c('A', 'B', 'C' ,'D'), colB = c(1,1,1,1)) 
someList <- list(A=20, B=30, C=40, D=50) 
for(letter in names(someList)){ 
    smallFrame[smallFrame$colA==letter, 'newColumn'] <- someList[[letter]] 
} 

我該如何做一個循環?這不會做到這一點。

lapply(names(someList), function(x) {smallFrame[smallFrame$colA==x, 'newColumn'] <- someList[[x]]}) 

回答

7

這是一個簡單的合併,如果你重塑你smallList適當

# reshape2 for melt. 
library(reshape2) 
# slightly expanded version with duplicate colA == A 
smallFrame <- data.frame(colA = c('A', 'A', 'B', 'C' ,'D'), colB = c(1,2,1,1,1)) 
someList <- list(A=20, B=30, C=40, D=50) 
merge(smallFrame, melt(someList), by.x = 'colA', by.y = 'L1') 

    colA colB value 
1 A 1 20 
2 A 2 20 
3 B 1 30 
4 C 1 40 
5 D 1 50 

或,如果您真的熱衷於在smallFrame內有效分配,請使用data.table

library(data.table) 
smallDT <- data.table(smallFrame, key = 'colA') 
someDT <- data.table(melt(someList), key = 'L1') 

# left join smallDT and someDT, assigning the `value` column by reference 
# within smallDT as the column `newColumn` 
smallDT[someDT, newColumn := value] 




smallDT 
    colA colB newColumn 
1: A 1  20 
2: A 2  20 
3: B 1  30 
4: C 1  40 
5: D 1  50 
+1

這太好了。我必須完全使用數據框並移至data.table。我現在已經學會了2到3次。 –

8

醜,但工程:

lapply(names(someList), function(x) {smallFrame[smallFrame$colA==x, 'newColumn'] <<- someList[[x]]}) 

注意<<-。它不會與<-一起工作的原因是someList的副本在函數中被修改。

這裏將「醜陋」表示爲不應該使用此語法,原因有兩個。首先,帶有副作用的功能容易出錯。其次,lapply的返回值被忽略。其中任何一個都表明明確的循環是最好的。

少醜,從@thelatemail幾乎被盜:

smallFrame$newColumn <- unlist(someList[match(smallFrame$colA, names(someList))]) 

例子:

smallFrame <- data.frame(colA = c('A', 'B', 'C' ,'D', 'A'), colB = c(1,1,1,1,1)) 
> smallFrame 

> smallFrame 
    colA colB 
1 A 1 
2 B 1 
3 C 1 
4 D 1 
5 A 1 

smallFrame$newColumn <- unlist(someList[match(smallFrame$colA, names(someList))]) 

> smallFrame 
    colA colB newColumn 
1 A 1  20 
2 B 1  30 
3 C 1  40 
4 D 1  50 
5 A 1  20 
+0

+1這是更好,更可擴展的解決方案。 – thelatemail

+0

謝謝。這工作。 –

+3

'lapply' +'<< - '通常意味着你應該使用for循環。 – hadley