R语言 使用其他数据框替换多个值

0h4hbjxa  于 2023-05-20  发布在  其他
关注(0)|答案(4)|浏览(105)

我想使用另一个数据框替换不同列中的不同值
df1

v1   v2 v3  v4
RDA  NA ILL NA
OPCS NA NA  NA
OJK  BR ILL PE

df2

v1  v2  v3  v5
RDA COL ILL P3
OPCS BR ILL P2

我希望输出 Dataframe 看起来像这样:

v1  v2  v3  v4 v5
RDA COL ILL NA P3
OPCS BR ILL NA P2
OJK  BR ILL PE NA

我尝试使用inner_join,但不起作用,看起来像这样

v1  v2.x v2.y v3.x v3.y v4 v5
RDA NA   COL  ILL  NA    NA P3
OPCS NA  BR   NA   ILL   NA P2

任何帮助将不胜感激。

ctehm74n

ctehm74n1#

这里有一个替代方案,如果你感兴趣:

library(data.table)
setDT(df1)
setDT(df2)

dcast(
  merge(melt(df1,"v1"), melt(df2,"v1"), by=c("v1", "variable"),all = T)[!is.na(value.y), value.x:=value.y],
  v1~variable, value.var = "value.x"
)

输出:

v1     v2     v3     v4     v5
   <char> <char> <char> <char> <char>
1:    OJK     BR    ILL     PE   <NA>
2:   OPCS     BR    ILL   <NA>     P2
3:    RDA    COL    ILL   <NA>     P3
pepwfjgg

pepwfjgg2#

library(dplyr)

new <- setdiff(names(df2), names(df1))
merge_vars <- "v1"

rows_patch(df1, select(df2, -all_of(new)), by = merge_vars) |>
  left_join(select(df2, all_of(c(merge_vars, new))), by = merge_vars)

?rows_patch仅覆盖NA值。如果你想更新任何值,你可以使用rows_update。注意,要使用rows_patchdf2中的所有列都需要存在于df1中,这就是为什么我使用setdiff来暂时删除“v5”。

输出

v1  v2  v3   v4 v5
1  RDA COL ILL <NA> P3
2 OPCS  BR ILL <NA> P2
qyyhg6bp

qyyhg6bp3#

我写了一个自定义函数multiple_replacer()

library(purrr)
library(dplyr)

multiple_replacer <- function(x, y){
bind_rows(list(A = df1, B = df2), .id = 'id') %>%
  reframe(cur_data()[seq(nrow(df1)), ], .by = id) %>%
  group_split(id) %>%
  map(~ select(., -id)) %>% 
  set_names(c("mat1", "mat2")) %>%
  imap(function(df, name) assign(name, as.matrix(df), envir = .GlobalEnv)) %>%
  { mat1 <- get("mat1", envir = .GlobalEnv)
  mat2 <- get("mat2", envir = .GlobalEnv)
  mat1[is.na(mat1)] <- mat2[is.na(mat1)]
  as.data.frame(mat1)
  }
}

multiple_replacer(df1, df2)
v1  v2  v3   v4   v5
1  RDA COL ILL <NA>   P3
2 OPCS  BR ILL <NA>   P2
3  OJK  BR ILL   PE <NA>
yv5phkfx

yv5phkfx4#

另一种选择是使用data.table

setDT(df1)
setDT(df2)

df1[df2, on="v1", 
    `:=`(v2 = fcoalesce(v2, i.v2),
         v3 = fcoalesce(v3, i.v3),
         v5 = i.v5)]

输出

v1     v2     v3     v4     v5
1:    RDA    COL    ILL   <NA>     P3
2:   OPCS     BR    ILL   <NA>     P2
3:    OJK     BR    ILL     PE   <NA>

相关问题