如何根据与第三列的匹配将数据框列中的值替换为另一列的值?

时间:2021-02-11 11:01:08

标签: r

我在尝试根据第三列之间的匹配将具有四个变量的数据帧的值转换为具有两个变量的另一个数据帧中特定列的值时遇到问题。

在数据帧 df1 中,我有一个 meta_#,它对应于与 meta_# 在同一行中表示的 iso_#。当数据帧中的 meta_# 匹配时,我希望相应的 iso_# 替换 df2 中的 meta_#。

使用简化的数据集,例如:

当 df1$V1 与 df2$V1、df2$V2、df2$V3 和 df2$V4 中任何值的值匹配时,我希望将 df2 中的值替换为 df1$V2 中的值与相应匹配项相同的行

df1

     V1      V2
1 meta_123 iso_321
2 meta_234 iso_987
3 meta_345 iso_876
4 meta_456 iso_765
5 meta_567 iso_543
6 meta_789 iso_423

df2

     V1        V2       V3      V4
1 meta_123 meta_234 meta_345 meta_456
2 meta_123 meta_234 meta_345 meta_567
3 meta_123 meta_345 meta_567 meta_789
4 meta_234 meta_567 meta_456 meta_789
etc...

然后我想要以下内容 df3

     V1      V2      V3     V4
1 iso_321 iso_987 iso_876 iso_765
2 iso_321 iso_987 iso_876 iso_543
3 iso_321 iso_876 iso_543 iso_423
4 iso_987 iso_543 iso_765 iso_423
etc...

我试过

df3 <- as.data.frame(ifelse(df2 %in% df1$V1, df1$V2))

但它只是按照原来的顺序返回 df1$V2 的列表。

有人可以帮我吗?

2 个答案:

答案 0 :(得分:0)

您可以使用 match :

df2[] <- df1$V2[match(as.matrix(df2), df1$V1)]
df2

#       V1      V2      V3      V4
#1 iso_321 iso_987 iso_876 iso_765
#2 iso_321 iso_987 iso_876 iso_543
#3 iso_321 iso_876 iso_543 iso_423
#4 iso_987 iso_543 iso_765 iso_423

答案 1 :(得分:0)

我们可以使用tidyverse

library(dplyr)
library(tibble)
df2 %>%
     mutate(across(everything(), ~ deframe(df1)[.]))
#       V1      V2      V3      V4
#1 iso_321 iso_987 iso_876 iso_765
#2 iso_321 iso_987 iso_876 iso_543
#3 iso_321 iso_876 iso_543 iso_423
#4 iso_987 iso_543 iso_765 iso_423

或者使用 base R

df2[] <- setNames(df1$V2, df1$V1)[as.matrix(df2)]

数据

df1 <- structure(list(V1 = c("meta_123", "meta_234", "meta_345", "meta_456", 
"meta_567", "meta_789"), V2 = c("iso_321", "iso_987", "iso_876", 
"iso_765", "iso_543", "iso_423")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6"))

df2 <- structure(list(V1 = c("meta_123", "meta_123", "meta_123", "meta_234"
), V2 = c("meta_234", "meta_234", "meta_345", "meta_567"), V3 = c("meta_345", 
"meta_345", "meta_567", "meta_456"), V4 = c("meta_456", "meta_567", 
"meta_789", "meta_789")), class = "data.frame", row.names = c("1", 
"2", "3", "4"))