R - 使用 grepl 的条件模式匹配
R - conditional pattern matching using grepl
我有两个数据框,像这样:
name <- c("joe", "kim", "kerry", "david")
name2 <- c("kim", "david", "joe", "kerry")
school <- c("cambridge", "south carolina", "vermont binghamton", "delaware")
school2 <- c("south carolina", "delaware", "cambridge magdalene", "vermont")
df1 <- data.frame(name, school)
df2 <- data.frame(name2, school2)
我想做的是:
- 在
df2$name2
中搜索 df1$name
中的匹配项。
- 如果找到匹配项,请比较匹配行中的
df2$school2
和 df1$school
。
- 如果在
df1$school
中找不到 df2$school2
的匹配项,df2$perfect.match
列中的 return FALSE
例如,由于 df2
中的 "joe" 与 df1
中的 "joe" 相匹配,因此存在匹配。但是,由于两者中 "school" 的值不同,因此 df2
中第三行的值为 FALSE 的列。 df2
.
中的第 4 行相同
我试过使用 grep 和 grepl。我认为 grepl 是最好的,因为它 return 是一个逻辑值。我试过的是:
df2$perfect.match <- ifelse(grepl(paste(df2$name2, collapse = "|"),
df1$name, fixed = F) & grepl(paste(df2$school2, collapse = "|"), df1$school, fixed = F), "", "FALSE")
然而,我得到的只是:
name2 school2 perfect.match
1 kim south carolina FALSE
2 david delaware
3 joe cambridge magdalene
4 kerry vermont
当我想要的结果是:
df2
name2 school2 perfect.match
1 kim south carolina
2 david delaware
3 joe cambridge magdalene FALSE
4 kerry vermont FALSE
如果可以的话,最好快点。真正的数据框非常大。谢谢。
更新:
我还希望能够强制 df2$school
的行具有与 df1$school
中对应的 name
匹配项相同的值,就像这样:
name2 school2
1 kim south carolina
2 david delaware
3 joe cambridge
4 kerry vermont binghamton
你可以做...
df2$perfect.match <- paste(df2$name2, df2$school2) %in% paste(df1$name, df1$school)
df2
name2 school2 perfect.match
1 kim south carolina TRUE
2 david delaware TRUE
3 joe cambridge magdalene FALSE
4 kerry vermont FALSE
比将列粘贴在一起稍微快一些:
matches <- df2$name2 %in% df1$name
df2$perfect.match <- df2$school2[matches] %in% df1$school
microbenchmark::microbenchmark(
v1 = {matches <- df2$name2 %in% df1$name
df2$perfect.match <- df2$school2[matches] %in% df1$school
},
v2 = {df2$perfect.match <- paste(df2$name2, df2$school2) %in% paste(df1$name, df1$school)}
)
使用dplyr
,您可以:
dfX <- df1 %>%
bind_rows(.,df2) %>%
group_by(name) %>%
distinct(school) %>%
count(name, name = "perfect.matched") %>%
left_join(df2,.,by = 'name') %>%
mutate(., perfect.matched = ifelse(perfect.matched ==1,"","FALSE"))
并获得以下输出:
> dfX
name school perfect.matched
1 kim south carolina
2 david delaware
3 joe cambridge magdalene FALSE
4 kerry vermont FALSE
我们可以使用 match
和 %in%
。 grepl
不会在这里,因为这是精确匹配而不是模式匹配。
df2$perfect_match <- df2$school2 %in% df1$school[match(df2$name2, df1$name)]
df2
# name2 school2 perfect_match
#1 kim south carolina TRUE
#2 david delaware TRUE
#3 joe cambridge magdalene FALSE
#4 kerry vermont FALSE
我有两个数据框,像这样:
name <- c("joe", "kim", "kerry", "david")
name2 <- c("kim", "david", "joe", "kerry")
school <- c("cambridge", "south carolina", "vermont binghamton", "delaware")
school2 <- c("south carolina", "delaware", "cambridge magdalene", "vermont")
df1 <- data.frame(name, school)
df2 <- data.frame(name2, school2)
我想做的是:
- 在
df2$name2
中搜索df1$name
中的匹配项。 - 如果找到匹配项,请比较匹配行中的
df2$school2
和df1$school
。 - 如果在
df1$school
中找不到df2$school2
的匹配项,df2$perfect.match
列中的 return FALSE
例如,由于 df2
中的 "joe" 与 df1
中的 "joe" 相匹配,因此存在匹配。但是,由于两者中 "school" 的值不同,因此 df2
中第三行的值为 FALSE 的列。 df2
.
我试过使用 grep 和 grepl。我认为 grepl 是最好的,因为它 return 是一个逻辑值。我试过的是:
df2$perfect.match <- ifelse(grepl(paste(df2$name2, collapse = "|"),
df1$name, fixed = F) & grepl(paste(df2$school2, collapse = "|"), df1$school, fixed = F), "", "FALSE")
然而,我得到的只是:
name2 school2 perfect.match
1 kim south carolina FALSE
2 david delaware
3 joe cambridge magdalene
4 kerry vermont
当我想要的结果是:
df2
name2 school2 perfect.match
1 kim south carolina
2 david delaware
3 joe cambridge magdalene FALSE
4 kerry vermont FALSE
如果可以的话,最好快点。真正的数据框非常大。谢谢。
更新:
我还希望能够强制 df2$school
的行具有与 df1$school
中对应的 name
匹配项相同的值,就像这样:
name2 school2
1 kim south carolina
2 david delaware
3 joe cambridge
4 kerry vermont binghamton
你可以做...
df2$perfect.match <- paste(df2$name2, df2$school2) %in% paste(df1$name, df1$school)
df2
name2 school2 perfect.match
1 kim south carolina TRUE
2 david delaware TRUE
3 joe cambridge magdalene FALSE
4 kerry vermont FALSE
比将列粘贴在一起稍微快一些:
matches <- df2$name2 %in% df1$name
df2$perfect.match <- df2$school2[matches] %in% df1$school
microbenchmark::microbenchmark(
v1 = {matches <- df2$name2 %in% df1$name
df2$perfect.match <- df2$school2[matches] %in% df1$school
},
v2 = {df2$perfect.match <- paste(df2$name2, df2$school2) %in% paste(df1$name, df1$school)}
)
使用dplyr
,您可以:
dfX <- df1 %>%
bind_rows(.,df2) %>%
group_by(name) %>%
distinct(school) %>%
count(name, name = "perfect.matched") %>%
left_join(df2,.,by = 'name') %>%
mutate(., perfect.matched = ifelse(perfect.matched ==1,"","FALSE"))
并获得以下输出:
> dfX
name school perfect.matched
1 kim south carolina
2 david delaware
3 joe cambridge magdalene FALSE
4 kerry vermont FALSE
我们可以使用 match
和 %in%
。 grepl
不会在这里,因为这是精确匹配而不是模式匹配。
df2$perfect_match <- df2$school2 %in% df1$school[match(df2$name2, df1$name)]
df2
# name2 school2 perfect_match
#1 kim south carolina TRUE
#2 david delaware TRUE
#3 joe cambridge magdalene FALSE
#4 kerry vermont FALSE