如果另一个数据框中存在组合,则 R 检查行
R check row for row if a combination exists in another dataframe
我在 R 中有两个数据框(df1 和 df2),除了两列,一个人号 (pnr) 和一个药物名称 (name) 之外,它们具有不同的信息。 df1 中的行,我想检查 pnr 和名称的组合是否存在于 df2 中的某处。如果存在这种组合,我希望 "yes" 在 df1 的另一列中。如果不是 "no".
df1
pnr|drug|...|check
---|----|---|-----
1 | 1 |...| no
1 | 2 |...| yes
2 | 2 |...| yes
3 | 2 |...| no
.....
df2
pnr|drug|...|
---|----|---|
1 | 2 |...|
2 | 2 |...|
....
比如我要检查,df2中是否存在行组合pnr=1 & drug=1(否),pnr=1 & drug=2(是)等,然后放置一个"yes" 或 "no" 在 df1
的检查栏中
我尝试了以下 for
语句,但没有成功。它确实在 "check" 列中放置了一个“是或 "no",但它没有正确地做
for(index in 1:nrow(df1)){
if((df1[index,]$pnr %in% df2$pnr)&(df1[index,]$name %in% df2$name)){
check_text="yes"}else{check_text="no"}
df1$check=check_text
}
我觉得我应该使用 apply
,但我一直没弄明白。你们知道如何解决这个问题吗?
一种方法是使用 base R
方法。
将 pnr
和 drug
列粘贴在一起并在 df1
中找到相似的 match
df1$check <- ifelse(is.na(match(paste0(df1$pnr, df1$drug),
paste0(df2$pnr, df2$drug))),"No", "Yes")
# pnr drug check
#1 1 1 No
#2 1 2 Yes
#3 2 2 Yes
#4 3 2 No
我们可以使用 apply
,使用 any
函数检查匹配:
df1$check <-
apply(df1, 1, function(x)
ifelse(any(x[1] == df2$pnr & x[2] == df2$drug), 'yes','no'))
# df1
# pnr drug check
# 1 1 1 no
# 2 1 2 yes
# 3 2 2 yes
# 4 3 2 no
数据
df1 <- data.frame(pnr = c(1,1,2,3),
drug = c(1,2,2,2))
df2 <- data.frame(pnr = c(1,2),
drug = c(2,2))
这对于 dplyr::left_join
来说很自然:
library(dplyr) # for left_join, transmute
library(tidyr) # for replace_na
df1 <- expand.grid(pnr = 1:3, drug = 1:3)
df2 <- data.frame(pnr = c(1, 3), drug = c(2, 1))
df1 <- df1 %>%
left_join(df2 %>% transmute(pnr, drug, check = 'yes')) %>%
replace_na(list(check = 'no'))
df1
#> pnr drug check
#> 1 1 1 no
#> 2 2 1 no
#> 3 3 1 yes
#> 4 1 2 yes
#> 5 2 2 no
#> 6 3 2 no
#> 7 1 3 no
#> 8 2 3 no
#> 9 3 3 no
我在 R 中有两个数据框(df1 和 df2),除了两列,一个人号 (pnr) 和一个药物名称 (name) 之外,它们具有不同的信息。 df1 中的行,我想检查 pnr 和名称的组合是否存在于 df2 中的某处。如果存在这种组合,我希望 "yes" 在 df1 的另一列中。如果不是 "no".
df1
pnr|drug|...|check
---|----|---|-----
1 | 1 |...| no
1 | 2 |...| yes
2 | 2 |...| yes
3 | 2 |...| no
.....
df2
pnr|drug|...|
---|----|---|
1 | 2 |...|
2 | 2 |...|
....
比如我要检查,df2中是否存在行组合pnr=1 & drug=1(否),pnr=1 & drug=2(是)等,然后放置一个"yes" 或 "no" 在 df1
的检查栏中我尝试了以下 for
语句,但没有成功。它确实在 "check" 列中放置了一个“是或 "no",但它没有正确地做
for(index in 1:nrow(df1)){
if((df1[index,]$pnr %in% df2$pnr)&(df1[index,]$name %in% df2$name)){
check_text="yes"}else{check_text="no"}
df1$check=check_text
}
我觉得我应该使用 apply
,但我一直没弄明白。你们知道如何解决这个问题吗?
一种方法是使用 base R
方法。
将 pnr
和 drug
列粘贴在一起并在 df1
match
df1$check <- ifelse(is.na(match(paste0(df1$pnr, df1$drug),
paste0(df2$pnr, df2$drug))),"No", "Yes")
# pnr drug check
#1 1 1 No
#2 1 2 Yes
#3 2 2 Yes
#4 3 2 No
我们可以使用 apply
,使用 any
函数检查匹配:
df1$check <-
apply(df1, 1, function(x)
ifelse(any(x[1] == df2$pnr & x[2] == df2$drug), 'yes','no'))
# df1
# pnr drug check
# 1 1 1 no
# 2 1 2 yes
# 3 2 2 yes
# 4 3 2 no
数据
df1 <- data.frame(pnr = c(1,1,2,3),
drug = c(1,2,2,2))
df2 <- data.frame(pnr = c(1,2),
drug = c(2,2))
这对于 dplyr::left_join
来说很自然:
library(dplyr) # for left_join, transmute
library(tidyr) # for replace_na
df1 <- expand.grid(pnr = 1:3, drug = 1:3)
df2 <- data.frame(pnr = c(1, 3), drug = c(2, 1))
df1 <- df1 %>%
left_join(df2 %>% transmute(pnr, drug, check = 'yes')) %>%
replace_na(list(check = 'no'))
df1
#> pnr drug check
#> 1 1 1 no
#> 2 2 1 no
#> 3 3 1 yes
#> 4 1 2 yes
#> 5 2 2 no
#> 6 3 2 no
#> 7 1 3 no
#> 8 2 3 no
#> 9 3 3 no