1

我正在尝试在mutate(). 假设我们从一个df1看起来像这样的数据框开始,由它下面的代码生成:

  ID Status
1  1      N
2  2      Y
3  3      Y
4  4      N
5  5      Y

df1 <- data.frame(
  ID = c(1,2,3,4,5),
  Status = c("N","Y","Y","N","Y")
)

我使用 dplyr 的mutate()函数根据最右边的“状态”列的值生成一个新列。下面是新的tmp数据帧输出和生成它的 dplyr 代码(这是一个超级简单的例子,适用于我的更大问题 - 就这样吧):

  ID Status Flag
1  1      N   No
2  2      Y  Yes
3  3      Y  Yes
4  4      N   No
5  5      Y  Yes

tmp <- 
  df1 %>% 
  mutate("Flag"=case_when(Status=="Y"~"Yes",TRUE~"No"))

我试图在上面嵌入等效的“匹配”函数,mutate()以便插入到标志列中的值取决于与df1这两个附加数据帧中的 ID 匹配的数据帧中的 ID:

Status1 <- data.frame(ID = c(2,3))
Status2 <- data.frame(ID = c(5)) 

例如,使用 ID 匹配函数,我的tmp输出将如下所示:

  ID Status Flag             [Flag explained]
1  1      N   No
2  2      Y  Yes - Status1   Since the ID in the df1 data frame matches one of the ID's in the Status 1 data frame
3  3      Y  Yes - Status1   Same as immediately above
4  4      N   No
5  5      Y  Yes - Status2   Since the ID in the df1 data frame matches the ID in the Status 2 data frame

在 dplyr 中以这种方式匹配多个数据帧的任何想法?

在我正在使用的实际数据中,有 5 个数据帧要匹配,而不是像本例中的 2 个。此外,在我实际的 5 个匹配表中,所有 ID 都是互斥的(匹配表中没有重复 ID)。在我的实际数据中,Status 和 Flag 列的等价物也是字符串,而不是数值。

4

2 回答 2

5

一种方法是使用更新的Status*帧进行多次连接:

Status1 <- data.frame(ID = c(2,3), Flag = "Status1")
Status2 <- data.frame(ID = c(5), Flag = "Status2") 

library(dplyr)
df1 %>%
  left_join(Status1, by = "ID") %>%
  left_join(Status2, by = "ID") %>%
  mutate(Flag = coalesce(Flag.x, Flag.y), Flag = if_else(is.na(Flag), "No", Flag)) %>%
  select(-Flag.x, -Flag.y)
#   ID Status    Flag
# 1  1      N      No
# 2  2      Y Status1
# 3  3      Y Status1
# 4  4      N      No
# 5  5      Y Status2

或者更简单地说:

df1 %>%
  left_join(bind_rows(Status1, Status2), by = "ID") %>%
  mutate(Flag = if_else(is.na(Flag), "No", Flag))
#   ID Status    Flag
# 1  1      N      No
# 2  2      Y Status1
# 3  3      Y Status1
# 4  4      N      No
# 5  5      Y Status2

连接/合并的前提最初可能很难可视化,两个很好的参考资料是如何连接(合并)数据帧(内、外、左、右)INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN 有什么区别? .

于 2022-01-07T19:48:02.367 回答
1

另一种方法可以是这样的:

library(tidyverse)

df1 %>%
  mutate("Flag" = case_when(
    ID %in% Status1$ID ~ "Status1",
    ID %in% Status2$ID ~ "Status2",
    TRUE ~ Status
  ))
#>   ID Status    Flag
#> 1  1      N       N
#> 2  2      Y Status1
#> 3  3      Y Status1
#> 4  4      N       N
#> 5  5      Y Status2

reprex 包于 2022-01-07 创建(v2.0.1)

数据:

df1 <- data.frame(
  ID = c(1, 2, 3, 4, 5),
  Status = c("N", "Y", "Y", "N", "Y")
)
Status1 <- data.frame(ID = c(2, 3))
Status2 <- data.frame(ID = c(5))
于 2022-01-08T01:20:02.390 回答