2013-02-10 43 views
2

我需要有選擇地更新df列中的值,具體取決於列上的條件滿足情況在df2中,併爲df1提供df2列中的值作爲更新值。兩個df都有一個col,其值是唯一的,df2中的唯一標識符是df1中的唯一標識符。我試過的方法是在兩個df中採用唯一列值,並將它們轉換爲行名稱,使用它們來定義一個選擇索引,該索引由df2創建,然後應用於df1以進行值更新。通過使用數字下標定義列,並結合基於字符的行共享密鑰索引,我得到了可以工作的語法(最終!)。呼。更新df col值,使用另一個df中col上的條件時,當兩個df中的char col可以充當鍵時

但是有沒有比我嘗試的更簡單,更有效,更「R」的方式,使用內置,也許?我需要擴展。測試例子如下:

goo <- data.frame(Uids=c("UidD", "UidA", "UidC"), Payout=c(3,0,5), stringsAsFactors = FALSE) 
moo <- data.frame(Uids=c("UidB", "UidC", "UidA", "UidD"), PayOut=0, stringsAsFactors = FALSE) 
goo 
    Uids Payout 
1 UidD  3 
2 UidA  0 
3 UidC  5 
moo 
    Uids PayOut 
1 UidB  0 
2 UidC  0 
3 UidA  0 
4 UidD  0 
# I want to update moo$Payout with the value of goo$Payout, for matching Uids, 
# when goo$Payout > 0, i.e. moo[4,2] <- goo[1,2]; moo[2,2 <- goo[3,2] 
rownames(goo) <- goo$Uids 
rownames(moo) <- moo$Uids 
#I am trying to create and apply an index based on turning uids into rownames 
IndexToUpdate <- goo$Uids[goo$Payout>0] 
IndexToUpdate 
[1] "UidD" "UidC" 
moo[IndexToUpdate, 2] <- goo[IndexToUpdate, 2] 
#this works, but is there a better way to do it? 
moo 
    Uids PayOut 
UidB UidB  0 
UidC UidC  5 
UidA UidA  0 
UidD UidD  3 

回答

3

我會用mergeall.x = TRUE

voo <- merge(moo, goo, by = "Uids", all.x = TRUE) 
voo 
# Uids PayOut.x PayOut.y 
# 1 UidA  0  0 
# 2 UidB  0  NA 
# 3 UidC  0  5 
# 4 UidD  0  3 

然後ifelse

within(voo, PayOut <- ifelse(is.na(PayOut.y), PayOut.x, PayOut.y)) 
# Uids PayOut.x PayOut.y PayOut 
# 1 UidA  0  0  0 
# 2 UidB  0  NA  0 
# 3 UidC  0  5  5 
# 4 UidD  0  3  3 

使用data.table S也是一樣的東西:

library(data.table) 
GOO <- data.table(goo) 
MOO <- data.table(moo) 
setkey(GOO, Uids) 
setkey(MOO, Uids) 
VOO <- GOO[MOO] 
VOO[, FinalPayout := ifelse(is.na(PayOut), PayOut.1, PayOut)] 
+0

謝謝,flodel。沒有拿起all.x標誌合併,這使得它成爲可能。 (除了你提供的整理操作外)Arun和flodel還沒有開始使用data.table - 我仍然試圖讓自己的頭腦基本瞭解 - 但它在SO建議中經常出現,所以它可能會排隊跳轉。 – 2013-02-10 14:44:50

相關問題