R语言:如何识别数据框行内T类变量的重复元素?
解决每行重复元素标记问题
首先,我们先复现你的示例数据框,方便测试:
# 构建示例数据框 df <- data.frame( T1 = c("a1", "c1", "e1", "d1", "a3", "f1", "f2"), T2 = c("b1", "d1", "a1", "b2", "a3", "f1", "f3"), T3 = c(NA, NA, "e1", "d1", NA, "a4", "f3"), T4 = c(NA, NA, NA, "b2", NA, "b3", "f5"), T5 = c(NA, NA, NA, NA, NA, "a4", "f6"), T6 = c(NA, NA, NA, NA, NA, NA, "f7"), T7 = c(NA, NA, NA, NA, NA, NA, "c1"), T8 = c(NA, NA, NA, NA, NA, NA, "c1"), T9 = c(NA, NA, NA, NA, NA, NA, "f2"), T10= c(NA, NA, NA, NA, NA, NA, "f3"), stringsAsFactors = FALSE )
正确的解决方案
你可以用两种方式实现预期的标记列D:
方法1:通过长度比较判断重复
这种方式逻辑直观,先过滤每行的NA值,再对比原非NA元素长度和去重后的长度:
df$D <- apply(df, 1, function(row) { # 提取当前行的非NA元素 non_na_vals <- row[!is.na(row)] # 若非NA元素长度 > 去重后的长度,说明存在重复 length(non_na_vals) != length(unique(non_na_vals)) })
方法2:使用duplicated()结合any()
利用duplicated()的incomparables = NA参数忽略空值,再用any()判断是否存在重复元素:
df$D <- apply(df, 1, function(row) { any(duplicated(row, incomparables = NA)) })
运行上述任意一种代码后,你会得到预期的结果:
> df$D [1] FALSE FALSE TRUE TRUE TRUE TRUE TRUE
分析你之前代码的问题
1. 自定义函数dupl的问题
- 你在函数里直接修改全局变量
df$D,每次循环都会覆盖整个列的值,而不是给对应行赋值,最终所有行都会变成最后一次循环的结果; duplicated(x[i])返回的是一个和当前行长度相同的逻辑向量(每个元素标记是否是重复项),而if()需要单个逻辑值,这里会触发长度不匹配的错误。
2. 第二种apply代码的问题
你用了df[-1]作为apply的输入,这会排除数据框的第一列(T1),导致部分行的重复元素没被检测到。比如第三行的T1(e1)和T3(e1)是重复的,但因为排除了T1,代码无法识别这个重复,所以返回错误的结果。只要把df[-1]改成df,就能得到正确结果。
内容的提问来源于stack exchange,提问作者Malna




