使用dplyr识别data.frame重复行并添加0/1标记变量
我来帮你用dplyr搞定这两个标记需求,代码简洁流畅,完全贴合你的要求:
首先咱们先构造示例数据,方便后续演示:
library(dplyr) library(purrr) # 处理近似重复需要用到这个包 # 构造你给出的示例数据 df <- tibble( A = c(1, 1, 0, 0, 1), B = c(0, 0, 1, 1, 1), C = c(1, 1, 1, 1, 1), D = c(1, 1, 1, 1, 1) )
1. 添加完全重复标记变量E
要标记所有存在完全重复的行(包括第一次出现的重复行),我们可以结合duplicated()的双向检查,再转成0/1型变量:
df <- df %>% mutate(E = as.integer(duplicated(.) | duplicated(., fromLast = TRUE)))
解释:duplicated(.)会标记除第一次出现外的重复行,duplicated(., fromLast = TRUE)会标记除最后一次出现外的重复行,两者取或就能覆盖所有重复行,最后用as.integer()把逻辑值转成0/1。
2. 添加近似重复标记变量F
这里的近似重复定义是:存在其他行与当前行仅单个列不同。我们可以用rowwise()逐行处理,结合purrr计算每行与其他行的差异列数,再判断是否存在符合条件的行:
df <- df %>% rowwise() %>% mutate( # 计算当前行与每一行的差异列数(包括自身) diff_counts = list(map_int(1:nrow(df), ~ sum(c_across(A:D) != df[.x, ]))), # 判断是否存在其他行与当前行仅单个列不同(排除自身的差异数0) F = as.integer(any(diff_counts == 1)) ) %>% ungroup() %>% select(-diff_counts) # 移除中间计算变量
解释:c_across(A:D)选中所有要比较的列,map_int()遍历每一行计算差异列数,最后通过any(diff_counts == 1)判断是否存在满足条件的近似重复行,再转成0/1型变量。
最终得到的结果如下:
| A | B | C | D | E | F |
|---|---|---|---|---|---|
| 1 | 0 | 1 | 1 | 1 | 1 |
| 1 | 0 | 1 | 1 | 1 | 1 |
| 0 | 1 | 1 | 1 | 1 | 1 |
| 0 | 1 | 1 | 1 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 | 1 |
完全符合你的要求:E标记了所有完全重复行,F标记了存在单个列差异的近似重复行。
内容的提问来源于stack exchange,提问作者Syd Amerikaner
相关产品推荐
相关产品推荐

