繁体   English   中英

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)

我想做的是以下几点:

  1. df1$name中搜索df2$name2以查找匹配项。
  2. 如果找到匹配项, df2$school2与匹配行中的df1$school进行比较。
  3. 如果在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM