[英]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)
我想做的是以下几点:
df1$name
中搜索df2$name2
以查找匹配项。df2$school2
与匹配行中的df1$school
进行比较。df1$school
中找不到df2$school2
的匹配项,则在df2$perfect.match
$perfect.match 列中返回 FALSE 例如,由于df2
中的“joe”与df1
中的“joe”匹配,因此存在匹配项。 但是,由于两者中“学校”的值不相同,因此df2
中的列将是第三行中值为 FALSE 的列。 df2
中的第 4 行相同。
我试过使用 grep 和 grepl。 我认为 grepl 会是最好的,因为它返回一个逻辑值。 我尝试的是:
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
如果可能的话,最好的东西是快速的。 真正的 dataframe 相当大。 谢谢。
更新:
我还希望能够强制错误的行具有与df1$school
中相应name
匹配的df2$school
相同的值,如下所示:
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"))
并得到以下output:
> 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.