合并不相等的数据帧并用0替换缺失的行

时间:2011-05-11 14:15:08

标签: r merge dataframe

我有两个data.frames,一个只有字符,另一个有字符和值。

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什么都没有。我想d和e也在合并表中,0 0条件。因此,对于df2 data.frame中的每个缺失行,0必须放在df1表中,如:

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

6 个答案:

答案 0 :(得分:85)

查看合并的帮助页面。 all参数允许您指定不同类型的合并。在这里,我们要设置all = TRUE。这将使合并返回NA为不匹配的值,我们可以使用is.na()更新为0:

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

多年后更新以解决跟进问题

您需要在第二个数据表中标识未合并的变量名称 - 我使用setdiff()。请查看以下内容:

df1 = data.frame(x=c('a', 'b', 'c', 'd', 'e', NA))
df2 = data.frame(x=c('a', 'b', 'c'),y1 = c(0,1,0), y2 = c(0,1,0))

#merge as before
df3 <- merge(df1, df2, all = TRUE)
#columns in df2 not in df1
unique_df2_names <- setdiff(names(df2), names(df1))
df3[unique_df2_names][is.na(df3[, unique_df2_names])] <- 0 

reprex package创建于2019-01-03(v0.2.1)

答案 1 :(得分:7)

或者,作为@ Chase代码的替代品,成为最近在数据库中具有背景的plyr粉丝:

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

答案 2 :(得分:3)

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))]

答案 3 :(得分:2)

我使用了Chase给出的答案(于2011年5月11日14:21回答),但我添加了一些代码来解决我的特定问题。

我有一个费率框架(用户,下载)和一个由用户合并的总计(用户,下载)框架,我想包括每个费率,即使没有相应的总数。但是,可能没有丢失的总数,在这种情况下,选择用NA替换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
}

答案 4 :(得分:1)

假设df1具有感兴趣的x的所有值,则可以使用dplyr::left_join()进行合并,然后使用base::replace()tidyr::replace_na()进行替换NA0一样:

library(tidyverse)

# dplyr only:
df_new <- 
  left_join(df1, df2, by = 'x') %>% 
  mutate(y = replace(y, is.na(y), 0))

# dplyr and tidyr:
df_new <- 
  left_join(df1, df2, by = 'x') %>% 
  mutate(y = replace_na(y, 0))

# In the sample data column `x` is a factor, which will give a warning with the join. This can be prevented by converting to a character before the join:
df_new <- 
  left_join(df1 %>% mutate(x = as.character(x)), 
            df2 %>% mutate(x = as.character(x)), 
            by = 'x') %>% 
    mutate(y = replace(y, is.na(y), 0))

答案 5 :(得分:1)

“所有”选项不再起作用,新参数为;

x = pd.merge(df1, df2, how="outer")