R语言如何批量逐行查找首列值的重复位置并忽略空值
R语言批量检测投票数据自投票记录方案
问题背景
当前需处理70行投票调研数据,计划编写R脚本完成数据清洗,核心需求为检测自投票行为:
- 数据结构:第一列为选民姓名,其余列对应不同投票类别下的投票对象,每行对应1位选民
- 检测逻辑:逐行检查该行首列的选民本人姓名是否在该行其他投票列中出现,定位重复值所在列,后续基于检测结果删除自投票记录
原有方案的问题
最初使用x[duplicated(x)]提取单行内重复值,测试第一行时可正确识别John Smith在最后一列的自投票记录,但存在三个明显缺陷:
- 无法批量运行,只能逐行手动执行代码
- 会将空值、NA误识别为重复值,例如Jane Doe行的两个空投票项会被错误标记,这类无效结果无需保留
- 会返回行内所有重复值,实际仅需要首列选民姓名的匹配结果,其他重复值无意义
测试数据构造代码
voter_name <- c("John Smith", "Jane Doe", "John Doe", "Beyonce") poll1 <- c("Spiderman", "The Hulk", "Superman", "Batman") poll2 <- c("Red", "", "Purple", "Yellow") poll3 <- c("Georgia", "", "Alaska", "Michigan") poll4 <- c("John Smith", "John Doe", "Beyonce", "Jane Doe") df <- data.frame(voter_name, poll1, poll2, poll3, poll4)
原有单行检测代码
RowVector = as.character(df[1, ]) RowVector[duplicated(RowVector)]
实现方案
不需要编写复杂循环,直接用apply()实现批量逐行检测,从匹配逻辑层面规避原有方法的所有问题:仅匹配首列选民姓名、自动跳过空值/NA、直接返回自投票对应的列位置。
# 统一将所有列转为字符型,避免因子类型导致的匹配异常 df[] <- lapply(df, as.character) # 逐行检测自投票位置 df$self_vote_col <- apply(df, 1, \(row) { target_name <- row[1] # 排除首列,仅检查投票列:匹配和选民姓名完全一致的非空、非NA值 match_pos <- which( row[-1] == target_name & nzchar(row[-1]) & !is.na(row[-1]) ) # 因排除了首列,索引偏移1位,无匹配则返回NA length(match_pos) > 0 ? match_pos + 1 : NA })
结果说明
在示例数据上运行后输出结果如下:
- 第1行(John Smith):自投票位置为第5列(poll4),返回值
5 - 第2行(Jane Doe):两个空投票项不会被误判,无自投票记录,返回值
NA - 第3行(John Doe):自投票位置为第5列(poll4),返回值
5 - 第4行(Beyonce):自投票位置为第5列(poll4),返回值
5
若单行存在多列自投票的情况,代码会返回所有匹配到的列位置;后续删除自投票记录时,直接过滤
is.na(df$self_vote_col)为FALSE的行即可。
内容的提问来源于stack exchange,提问作者user19447690
相关产品推荐
相关产品推荐

