R:使用其他数据帧更新数据帧

Zyf*_*ion 3 replace join r dataframe dplyr

假设我们的初始数据框如下所示:

df1 = data.frame(Index=c(1:6),A=c(1:6),B=c(1,2,3,NA,NA,NA),C=c(1,2,3,NA,NA,NA))

> df1
  Index A  B  C
1     1 1  1  1
2     2 2  2  2
3     3 3  3  3
4     4 4 NA NA
5     5 5 NA NA
6     6 6 NA NA
Run Code Online (Sandbox Code Playgroud)

另一个数据框包含col B和C的新信息

df2 = data.frame(Index=c(4,5,6),B=c(4,4,4),C=c(5,5,5))

> df2
  Index B C
1     4 4 5
2     5 4 5
3     6 4 5
Run Code Online (Sandbox Code Playgroud)

如何更新df1中的缺失值,使其如下所示:

  Index A B C
1     1 1 1 1
2     2 2 2 2
3     3 3 3 3
4     4 4 4 5
5     5 5 4 5
6     6 6 4 5
Run Code Online (Sandbox Code Playgroud)

我的尝试:

library(dplyr)

> full_join(df1,df2)
Joining by: c("Index", "B", "C")
  Index  A  B  C
1     1  1  1  1
2     2  2  2  2
3     3  3  3  3
4     4  4 NA NA
5     5  5 NA NA
6     6  6 NA NA
7     4 NA  4  5
8     5 NA  4  5
9     6 NA  4  5
Run Code Online (Sandbox Code Playgroud)

您可以看到,为4,5,6索引创建了重复的行,而不是替换NA值.

任何帮助将不胜感激!

akr*_*run 5

我们可以使用joindata.table. 将 'data.frame' 转换为 'data.table' ( setDT(df1),使用 "Index" 与 'df1' 连接并分配 ( :=),'B' 和 'C' 中的值与 'iB' 和 'i.C' .

library(data.table)
setDT(df1)[df2, c('B', 'C') := .(i.B, i.C), on = "Index"]
df1
#   Index A B C
#1:     1 1 1 1
#2:     2 2 2 2
#3:     3 3 3 3
#4:     4 4 4 5
#5:     5 5 4 5
#6:     6 6 4 5
Run Code Online (Sandbox Code Playgroud)

  • @Zyferion 这可能是因为您使用的是旧版本的“data.table”。请更新到新版本 (4认同)

the*_*ail 5

merge然后aggregate:

aggregate(. ~ Index, data=merge(df1, df2, all=TRUE), na.omit, na.action=na.pass )

#  Index B C A
#1     1 1 1 1
#2     2 2 2 2
#3     3 3 3 3
#4     4 4 5 4
#5     5 4 5 5
#6     6 4 5 6
Run Code Online (Sandbox Code Playgroud)

或者dplyr说:

df1 %>% 
    full_join(df2) %>%
    group_by(Index) %>%
    summarise_each(funs(na.omit))

#Joining by: c("Index", "B", "C")
#Source: local data frame [6 x 4]
#
#  Index     A     B     C
#  (dbl) (int) (dbl) (dbl)
#1     1     1     1     1
#2     2     2     2     2
#3     3     3     3     3
#4     4     4     4     5
#5     5     5     4     5
#6     6     6     4     5
Run Code Online (Sandbox Code Playgroud)