如何将匹配函数与变异函数一起使用?
How to use a match function with a mutate function?
我正在尝试在 mutate()
中嵌入一个匹配(或等效的 --- 我刚刚从 Excel 迁移而来,那里可以自由使用 Match)函数。假设我们从一个看起来像这样的数据框 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()
中嵌入一个等效的“匹配”函数,这样插入到 Flag 列中的值取决于 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 列相当于也是字符串,不是数值。
一种方法是使用更新的 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
joins/merges 的前提最初可能很难想象,两个很好的参考是 How to join (merge) data frames (inner, outer, left, right), What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?。
另一种方法可能是这样的:
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 package (v2.0.1)
创建于 2022-01-07
数据:
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))
我正在尝试在 mutate()
中嵌入一个匹配(或等效的 --- 我刚刚从 Excel 迁移而来,那里可以自由使用 Match)函数。假设我们从一个看起来像这样的数据框 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()
中嵌入一个等效的“匹配”函数,这样插入到 Flag 列中的值取决于 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 列相当于也是字符串,不是数值。
一种方法是使用更新的 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
joins/merges 的前提最初可能很难想象,两个很好的参考是 How to join (merge) data frames (inner, outer, left, right), What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?。
另一种方法可能是这样的:
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 package (v2.0.1)
创建于 2022-01-07数据:
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))