使用 dplyr 替换不同数据框中的多列
Replacing multiple columns from different dataframe using dplyr
我有两个数据框,其中一个包含 ID 的子集和另一个的列(但具有不同的值)。
ds1 <- data.frame(id = c(1:4),
d1 = "A",
d2 = "B",
d3 = "C")
ds2 <- data.frame(id = c(1,2),
d1 = "W",
d2 = "X")
我希望在 d1 上使用 dplyr 来查找共享列,并将它们的值替换为在 d2 中找到的值,匹配 ID。我可以像这样一次改变它们:
ds1 %>%
mutate(d1 = ifelse(id %in% ds2$id, ds2$d1[ds2$id==id],d1),
d2 = ifelse(id %in% ds2$id, ds2$d2[ds2$id==id],d2))
然而,在我的真实情况下,我需要这样做 47 次。以across()
的健壮性,我觉得还有更好的办法。我也对非 dplyr 解决方案持开放态度。
您可能需要使用 dplyr
和 stringr
(也可以在没有 stringr
的情况下完成)
library(tidyverse)
ds1 %>% left_join(ds2, by = 'id') %>%
mutate(across(ends_with('.y'), ~ coalesce(., get(str_replace(cur_column(), '.y', '.x'))))) %>%
select(!ends_with('.x')) %>%
rename_with(~str_remove(., '.y'), ends_with('.y'))
#> id d3 d1 d2
#> 1 1 C W X
#> 2 2 C W X
#> 3 3 C A B
#> 4 4 C A B
由 reprex package (v2.0.0)
于 2021-05-10 创建
这与我亲爱的朋友@AnilGoyal 发布的有点相似,与您的相比也有点冗长,您可以将其用于更大的数据集:
library(dplyr)
library(stringr)
ds1 %>%
left_join(ds2, by = "id") %>%
mutate(across(ends_with(".x"), ~ ifelse(!is.na(get(str_replace(cur_column(), ".x", ".y"))),
get(str_replace(cur_column(), ".x", ".y")),
.x))) %>%
select(!ends_with(".y")) %>%
rename_with(~ str_remove(., ".x"), ends_with(".x"))
id d1 d2 d3
1 1 W X C
2 2 W X C
3 3 A B C
4 4 A B C
使用rows_update
library(tidyverse)
ds1 <- data.frame(id = c(1:4),
d1 = "A",
d2 = "B",
d3 = "C")
ds2 <- data.frame(id = c(1,2),
d1 = "W",
d2 = "X")
rows_update(x = ds1, y = ds2, by = "id")
#> id d1 d2 d3
#> 1 1 W X C
#> 2 2 W X C
#> 3 3 A B C
#> 4 4 A B C
由 reprex package (v2.0.0)
创建于 2021-05-11
我有两个数据框,其中一个包含 ID 的子集和另一个的列(但具有不同的值)。
ds1 <- data.frame(id = c(1:4),
d1 = "A",
d2 = "B",
d3 = "C")
ds2 <- data.frame(id = c(1,2),
d1 = "W",
d2 = "X")
我希望在 d1 上使用 dplyr 来查找共享列,并将它们的值替换为在 d2 中找到的值,匹配 ID。我可以像这样一次改变它们:
ds1 %>%
mutate(d1 = ifelse(id %in% ds2$id, ds2$d1[ds2$id==id],d1),
d2 = ifelse(id %in% ds2$id, ds2$d2[ds2$id==id],d2))
然而,在我的真实情况下,我需要这样做 47 次。以across()
的健壮性,我觉得还有更好的办法。我也对非 dplyr 解决方案持开放态度。
您可能需要使用 dplyr
和 stringr
(也可以在没有 stringr
的情况下完成)
library(tidyverse)
ds1 %>% left_join(ds2, by = 'id') %>%
mutate(across(ends_with('.y'), ~ coalesce(., get(str_replace(cur_column(), '.y', '.x'))))) %>%
select(!ends_with('.x')) %>%
rename_with(~str_remove(., '.y'), ends_with('.y'))
#> id d3 d1 d2
#> 1 1 C W X
#> 2 2 C W X
#> 3 3 C A B
#> 4 4 C A B
由 reprex package (v2.0.0)
于 2021-05-10 创建这与我亲爱的朋友@AnilGoyal 发布的有点相似,与您的相比也有点冗长,您可以将其用于更大的数据集:
library(dplyr)
library(stringr)
ds1 %>%
left_join(ds2, by = "id") %>%
mutate(across(ends_with(".x"), ~ ifelse(!is.na(get(str_replace(cur_column(), ".x", ".y"))),
get(str_replace(cur_column(), ".x", ".y")),
.x))) %>%
select(!ends_with(".y")) %>%
rename_with(~ str_remove(., ".x"), ends_with(".x"))
id d1 d2 d3
1 1 W X C
2 2 W X C
3 3 A B C
4 4 A B C
使用rows_update
library(tidyverse)
ds1 <- data.frame(id = c(1:4),
d1 = "A",
d2 = "B",
d3 = "C")
ds2 <- data.frame(id = c(1,2),
d1 = "W",
d2 = "X")
rows_update(x = ds1, y = ds2, by = "id")
#> id d1 d2 d3
#> 1 1 W X C
#> 2 2 W X C
#> 3 3 A B C
#> 4 4 A B C
由 reprex package (v2.0.0)
创建于 2021-05-11