如何检查数据框行的一个元素中的字符串是否在另一个元素中

How to check if a string in one element of a dataframe row is in another element

我想查看有多少电子邮件地址包含电子邮件所有者的姓氏。

数据框中的每一行都包含一个姓氏和一个电子邮件地址。我想添加带有 "yes" 或 "no" 的第三列,表明该行的电子邮件中存在姓氏。

使用 for 循环很好...但我不禁想到可能有更好的 R 解决方案。关于如何使它更优雅的任何建议?

vec1 <- c("foo", "smith")
vec2 <- c("sfoo@x.com", "xxx@y.com")

df <- data.frame(vec1,vec2)


for(i in 1:nrow(df)) {
  if (grepl(df$vec1[i], df$vec2[i]) == TRUE) {
    df$lastNameInEmail[i] <- "Yes"
  } else {
    df$lastNameInEmail[i] <- "No"
  }
}

   vec1       vec2 lastNameInEmail
1   foo sfoo@x.com             Yes
2 smith  xxx@y.com              No

您可以使用 stringr str_detect

stringr::str_detect(vec2,paste(vec1,collapse = '|'))
[1]  TRUE FALSE

这是一个 data.table 替代方案,它适用于不止两个给定行:

vec1 <- c("foo", "smith", "jones", "bar")
vec2 <- c("sfoo@x.com", "xxx@y.com", "yyy@x.com", "sbar@x.com")

df <- data.frame(vec1,vec2)

library(data.table)
dt <- data.table(df)
dt[, lastNameInEmail:=ifelse(grepl(vec1, vec2) == TRUE, "Yes", "No"), by=vec1]
dt
    vec1       vec2 lastNameInEmail
1:   foo sfoo@x.com             Yes
2: smith  xxx@y.com              No
3: jones  yyy@x.com              No
4:   bar sbar@x.com             Yes

这假设 vec1 列是唯一的。

这是一个使用基本 R 函数的版本,它适用于不止两个给定的行:

vec1 <- c("foo", "smith", "jones", "bar")
vec2 <- c("sfoo@x.com", "xxx@y.com", "yyy@x.com", "sbar@x.com")

df <- data.frame(vec1,vec2)

df$lastNameInEmail <- sapply(1:nrow(df), function(x){ifelse(grepl(df$vec1[x], df$vec2[x])==TRUE, "Yes", "No")})
df
    vec1       vec2 lastNameInEmail
1:   foo sfoo@x.com             Yes
2: smith  xxx@y.com              No
3: jones  yyy@x.com              No
4:   bar sbar@x.com             Yes