2011-05-11 14 views
47

我有兩個data.frames,一個只有字符,另一個有字符和值。合併不相等的數據幀並用0替換缺失的行

df1 = data.frame(x=c('a', 'b', 'c', 'd', 'e')) 
df2 = data.frame(x=c('a', 'b', 'c'),y = c(0,1,0)) 
merge(df1, df2) 
    x y 
1 a 0 
2 b 1 
3 c 0 

我想合併df1和df2。字符a,b和c合併得很好,也有0,1,0但d和e沒有任何內容。我也想在合併表中使用0和0來表示d和e。因此,對於df2 data.frame中的每個缺失行,必須將0置於df1表中,如:

x y 
1 a 0 
2 b 1 
3 c 0 
4 d 0 
5 e 0 

回答

72

查看合併的幫助頁面。 all參數可讓您指定不同類型的合併。這裏我們要設置all = TRUE。這將使不匹配的值,我們可以更新到0 is.na()合併收益NA

zz <- merge(df1, df2, all = TRUE) 
zz[is.na(zz)] <- 0 

> zz 
    x y 
1 a 0 
2 b 1 
3 c 0 
4 d 0 
5 e 0 
+0

嗨大通,感謝您的解決方案!它對我有幫助! – Lisann 2011-05-12 06:51:58

+3

Hunh - 現在一直在使用R一年,我不知道你可以像這樣處理data.frame中的每個單元格。有時候可以質疑你的假設。謝謝Chase! – steamer25 2013-12-27 20:36:51

+0

嗨大通,我可以使用命令「all = true」僅適用於df1。有時此命令包含的數據在df1中不可用,但可用於df2 – jbest 2014-12-08 09:04:12

7

或者,作爲替代@大通的代碼,是一個最近plyr風扇與背景數據庫:

require(plyr) 
zz<-join(df1, df2, type="left") 
zz[is.na(zz)] <- 0 
2

data.table的另一種選擇。

實例數據

dt1 <- data.table(df1) 
dt2 <- data.table(df2) 
setkey(dt1,x) 
setkey(dt2,x) 

CODE

dt2[dt1,list(y=ifelse(is.na(y),0,y))] 
+0

在版本1.10.4中,您不需要'setkey'並且可以使用'df2 [df1,on =「x」] [is.na(y),y := 0]'在創建data.tables後立即生成所需的結果。 – lmo 2017-07-20 19:35:52

2

我用大通給出的答案(回答5月11日在'11 14:21),但我加了一些代碼來應用解決我的特殊問題。

我有一個價格框架(用戶,下載)和一個合計框架(用戶,下載)由用戶合併,我想包括每一個費率,即使沒有相應的總額。但是,可能沒有缺失總數,在這種情況下,選擇用於將NA替換爲零的行將失敗。

第一行代碼進行合併。接下來的兩行更改合併框架中的列名稱。 if語句將NA替換爲零,但前提是存在NA的行。

# merge rates and totals, replacing absent totals by zero 
graphdata <- merge(rates, totals, by=c("user"),all.x=T) 
colnames(graphdata)[colnames(graphdata)=="download.x"] = "download.rate" 
colnames(graphdata)[colnames(graphdata)=="download.y"] = "download.total" 
if(any(is.na(graphdata$download.total))) { 
    graphdata[is.na(graphdata$download.total),]$download.total <- 0 
}