如何在R循环中将变量列表视为数据框列名而非字符串?
问题解决:检测子字符串是否存在于指定列中
原代码问题分析
- 核心错误:直接将列名字符串传入
grepl,而非列的实际数据。cod_acme_raw_vars[[i]]是列名(如"ucod"),不是deaths16_21中该列的数值,导致grepl一直在检查枪械代码是否出现在列名里,而非列内容中。 - 结果覆盖问题:每次循环都会重写
all_firearm列,最终仅保留最后一次循环的检查结果,无法累积所有列的匹配情况。
方案1:高效正则匹配(推荐)
通过将firearm_char合并为单个正则表达式,一次性检查所有枪械代码,再遍历各列累积匹配结果:
cod_acme_raw_vars <- c("ucod","acme1","acme2","acme3","acme4","acme5","acme6","acme7","acme8","acme9","acme10","acme11") firearm_char <- c("W32","W33","W34","X72","X73","X74","X93","X94","X95","Y22","Y23","Y24","Y350","U014") # 初始化all_firearm为全FALSE deaths16_21$all_firearm <- FALSE # 合并枪械代码为正则模式(|分隔表示匹配任意一个) firearm_pattern <- paste(firearm_char, collapse = "|") # 遍历每个目标列 for (col_name in cod_acme_raw_vars) { # 获取当前列的实际数据 col_data <- deaths16_21[[col_name]] # 检查当前列中是否有任意枪械代码匹配 current_matches <- grepl(firearm_pattern, col_data) # 累积匹配结果:只要任意列匹配,该行设为TRUE deaths16_21$all_firearm <- deaths16_21$all_firearm | current_matches }
方案2:修正嵌套循环
如果坚持使用嵌套循环,需修正列数据的获取方式,并通过逻辑或操作累积结果:
cod_acme_raw_vars <- c("ucod","acme1","acme2","acme3","acme4","acme5","acme6","acme7","acme8","acme9","acme10","acme11") firearm_char <- c("W32","W33","W34","X72","X73","X74","X93","X94","X95","Y22","Y23","Y24","Y350","U014") # 初始化all_firearm为全FALSE deaths16_21$all_firearm <- FALSE for (i in seq_along(cod_acme_raw_vars)) { # 关键:用[[获取列的实际数据,而非列名字符串 col_data <- deaths16_21[[cod_acme_raw_vars[i]]] for (j in seq_along(firearm_char)) { # 检查当前枪械代码是否在当前列的行中 current_matches <- grepl(firearm_char[j], col_data) # 累积结果:保留所有匹配情况 deaths16_21$all_firearm <- deaths16_21$all_firearm | current_matches } }
关键要点
- 使用
deaths16_21[[col_name]]获取列的实际数据,而非直接使用列名字符串。 - 通过
|逻辑或操作累积匹配结果,确保只要任意列、任意枪械代码匹配,该行的all_firearm就为TRUE。
内容的提问来源于stack exchange,提问作者rojopomme
相关产品推荐
相关产品推荐

