R合并到位

时间:2018-04-05 10:51:33

标签: r replace merge

我希望能够在合并中更新现有变量而不是添加。有人可以帮助基本R命令来完成这项任务吗?这是一个例子:

A1 <-c("0ZERO","1ONE","2TWO","3THREE","4FOUR")
A2 <-c("5FIVE","6SIX","7SEVEN","8EIGHT","9NINE")
B <-c("1ONE","2TWO","3THREE")
C <-c("5FIVE","7SEVEN","8EIGHT")
X <-c(1.2,1.3,1.4)

master.df<-data.frame(A1,A2)
slave1.df<-data.frame(B,X)

X<-c(2.1,2.1,2.3)
slave2.df<-data.frame(C,X)

这会产生一个数据帧但是存在一些NA,很好。

master.df<-merge(master.df,slave1.df,by.x="A1",by.y="B",all.x=TRUE)
master.df
     A1     A2   X
1  0ZERO  5FIVE  NA
2   1ONE   6SIX 1.2
3   2TWO 7SEVEN 1.3
4 3THREE 8EIGHT 1.4
5  4FOUR  9NINE  NA

现在,NA中存在X,我想在A2中查找slave2.df以更新X中的值。这就是我认为它可能有用的方式:

master.df[is.na(master.df$X),]<-merge(master.df[is.na(master.df$X),],slave2.df,by.x="A2",by.y="C",all.x=TRUE)
Warning messages:
 1: In `[<-.data.frame`(`*tmp*`, is.na(master.df$X), , value = list( :
   provided 4 variables to replace 3 variables
 2: In `[<-.factor`(`*tmp*`, iseq, value = c(1L, 5L)) :
   invalid factor level, NA generated
 3: In `[<-.factor`(`*tmp*`, iseq, value = c(1L, 5L)) :
   invalid factor level, NA generated

但事实并非如此。我想要的是:

head(master.df)
     A1     A2   X
1  0ZERO  5FIVE 2.1
2   1ONE   6SIX 1.2
3   2TWO 7SEVEN 1.3
4 3THREE 8EIGHT 1.4
5  4FOUR  9NINE  NA

注意NA仍然存在。由于我的设置,我需要能够做到这一点是基础R(但如果人们认为这是实现此任务的最佳方式,我可以请求包安装)。感谢。

1 个答案:

答案 0 :(得分:1)

您可以尝试tidyverse解决方案

library(tidyverse)
master.df %>% 
 left_join(slave1.df, by = c("A1" = "B")) %>% 
 left_join(slave2.df, by = c("A2" = "C")) %>% 
  mutate(X = ifelse(is.na(X.x), X.y, X.x)) %>% 
  select(1:2, X)
      A1     A2   X
1  0ZERO  5FIVE 2.1
2   1ONE   6SIX 1.2
3   2TWO 7SEVEN 1.3
4 3THREE 8EIGHT 1.4
5  4FOUR  9NINE  NA

在基地R你可以尝试

master.df[is.na(master.df$X),3] <- merge(master.df[is.na(master.df$X),],slave2.df,by.x="A2",by.y="C",all.x=TRUE)[,4]
master.df
      A1     A2   X
1  0ZERO  5FIVE 2.1
2   1ONE   6SIX 1.2
3   2TWO 7SEVEN 1.3
4 3THREE 8EIGHT 1.4
5  4FOUR  9NINE  NA

这是您的解决方案,在子集化方面略有改进。