R语言中for循环内grep函数无法正常工作的问题排查
问题解决:R中赋值时出现"replacement has length zero"错误
错误原因
你遇到的错误是因为df5里存在某个公司名称在CompMeta的Company列中找不到匹配项,这时候grep()会返回空向量,给df5$type[i]赋值空向量就会触发长度不匹配的报错。你测试的具体i值刚好是能匹配到的条目,所以没出现问题,但循环到无匹配的条目就会报错。
解决方案
方案1:修改循环,处理无匹配的情况
在循环里先判断匹配结果的长度,无匹配时赋值NA,避免报错:
for (i in 1:length(df5$Company1)) { # 获取匹配的索引 match_pos <- grep(df5$Company1[i], CompMeta$Company) # 有匹配就取对应类别,无匹配就赋值NA df5$type[i] <- if (length(match_pos) > 0) { CompMeta$`Company Category`[match_pos] } else { NA } }
如果需要精确匹配(而不是模糊匹配),把grep改成精确匹配的判断更稳妥:
for (i in 1:length(df5$Company1)) { match_pos <- which(CompMeta$Company == df5$Company1[i]) df5$type[i] <- if (length(match_pos) > 0) CompMeta$`Company Category`[match_pos] else NA }
方案2:用合并替代循环(更高效推荐)
R里不推荐用循环做这种匹配赋值,用merge或者dplyr的连接函数更简洁高效,还自动处理无匹配的情况:
用base R的merge:
# 只保留CompMeta里需要的列,和df5按公司名称左连接 df5 <- merge(df5, CompMeta[, c("Company", "Company Category")], by.x = "Company1", by.y = "Company", all.x = TRUE) # 把列名改成type colnames(df5)[colnames(df5) == "Company Category"] <- "type"
用dplyr的left_join:
library(dplyr) df5 <- df5 %>% left_join(CompMeta %>% select(Company, `Company Category`), by = c("Company1" = "Company")) %>% rename(type = `Company Category`)
注意事项
grep默认是正则表达式模糊匹配,如果公司名称里有.、*这类正则特殊字符,会导致匹配异常,这时候可以加fixed = TRUE参数做精确文本匹配:grep(df5$Company1[i], CompMeta$Company, fixed = TRUE)- 左连接(
all.x = TRUE或者left_join)会保留df5的所有行,无匹配的type列会自动填充NA,适合你的需求。
内容的提问来源于stack exchange,提问作者Talata
相关产品推荐
相关产品推荐

