R语言实现:判断邮箱是否属于目标域名及报错解决
问题描述
我有一列唯一的邮箱域名(例如@comp1.com、@comp2.com等),另有一个包含大量邮箱的数据集。希望新建一列target_email,若邮箱属于目标域名则返回TRUE,否则返回FALSE。尝试了以下代码:
df$target_email<-grepl(domain$Email, df$Email) df$target_email<-ifelse(grepl(domain$Email, df$Email), "TRUE", "FALSE") df$target_email<-sapply(domain$Email, \(string) any(grepl(string, df$target_email, fixed = TRUE)))
但均报错:
argument 'pattern' has length > 1 and only the first element will be used
或
replacement has 160 rows, data has 28446
补充示例:假设要筛选FAANG公司邮箱,示例数据如下:
df$email<-c("matt@apple.com", "tash@amazon.com", "a@coke.com", "b@netflix.com", "c@pepsi.com") domains$email<-c("apple.com", "netflix.com", "amazon.com", "google.com")
期望结果:
df$target_email<-c(TRUE, TRUE, FALSE, TRUE, FALSE)
报错原因
- 第一个错误:
grepl()的pattern参数默认只支持单个字符串,直接传入域名向量时,只会取第一个元素匹配,其余域名被忽略。 - 第二个错误:
sapply()遍历域名后返回的结果长度和domains一致(160行),但df有28446行,维度不匹配导致赋值失败。
解决方案
方法1:合并域名成正则表达式批量匹配
把所有目标域名拼接成一个正则模式,用|表示“或”逻辑,再一次性匹配所有邮箱:
# 构建匹配@+目标域名的正则模式 domain_pattern <- paste0("@", domains$email, collapse = "|") # 执行匹配,fixed=TRUE避免转义域名中的. df$target_email <- grepl(domain_pattern, df$email, fixed = TRUE)
示例验证:
df$email<-c("matt@apple.com", "tash@amazon.com", "a@coke.com", "b@netflix.com", "c@pepsi.com") domains$email<-c("apple.com", "netflix.com", "amazon.com", "google.com") domain_pattern <- paste0("@", domains$email, collapse = "|") df$target_email <- grepl(domain_pattern, df$email, fixed = TRUE) # 输出结果:[1] TRUE TRUE FALSE TRUE FALSE
方法2:提取邮箱域名后直接匹配
先从邮箱中提取@之后的域名部分,再用%in%判断是否在目标域名列表中,逻辑更直观:
# 提取@后面的域名 df$extracted_domain <- sub(".*@", "", df$email) # 判断是否属于目标域名 df$target_email <- df$extracted_domain %in% domains$email
示例验证结果和方法1完全一致,还能保留提取出的域名用于后续分析。
方法3:用stringr包简化代码
stringr::str_detect支持直接传入模式向量,自动处理“或”逻辑,代码更简洁:
library(stringr) df$target_email <- str_detect(df$email, paste0("@", domains$email))
内容的提问来源于stack exchange,提问作者lala345
相关产品推荐
相关产品推荐

