如何基于值对DataFrame的重复列进行分组识别?
解决DataFrame重复列的分组与汇总问题
看起来你想找出DataFrame中值完全重复的列并分组,最终得到A&C、B&D、E这三个分组对吧?你的数据里A和C列值完全一致,B和D一致,E是独立的,我们可以通过给每列生成唯一的"特征签名"来实现准确分组,比用summary的方法更可靠(因为不同列可能summary相同但实际值不同)。
第一步:确认你的数据结构
先把你的数据代码贴出来,方便后续操作:
A <- c(1,0,1) B <- c(1,0,0) C <- c(1,0,1) D <- c(1,0,0) E <- c(0,0,0) testframe <- data.frame(A=A,B=B,C=C,D=D,E=E)
第二步:生成列的特征签名并分组
我们可以把每列的元素拼接成一个字符串,作为该列的唯一标识,然后根据这个标识对列名进行分组:
# 为每列生成唯一的特征字符串(基于列的实际值) col_signatures <- sapply(testframe, function(x) paste(x, collapse = ",")) # 根据特征字符串对列名进行分组 col_groups <- split(names(testframe), col_signatures) # 查看分组结果 col_groups
运行后会得到你想要的分组结果:
$`0,0,0` [1] "E" $`1,0,0` [1] "B" "D" $`1,0,1` [1] "A" "C"
第三步:汇总数据(保留每组的代表列)
如果想得到去重后的DataFrame,只保留每组的第一个列作为代表:
# 提取每组的第一个列,生成汇总后的DataFrame summary_frame <- testframe[, sapply(col_groups, `[`, 1)] # 查看汇总结果 summary_frame
输出的汇总数据如下:
A B E 1 1 1 0 2 0 0 0 3 1 0 0
为什么你之前的方法可能不准确?
你尝试用duplicated(lapply(testframe, summary))来去重,但summary只统计列的描述性统计信息(比如最小值、中位数、均值等),如果有两列的统计特征相同但实际值顺序不同(比如c(1,0,1)和c(1,1,0)),summary会认为它们是"重复"的,但实际这两列的值并不完全一致。直接用列的实际值生成特征签名能避免这种误判。
用tidyverse工具的替代方法
如果你习惯使用dplyr和tidyr,也可以用tidyverse的方式实现分组:
library(dplyr) library(tidyr) # 转换为长格式,生成特征签名后分组 col_groups_tidy <- testframe %>% mutate(row = row_number()) %>% pivot_longer(-row, names_to = "col", values_to = "val") %>% group_by(col) %>% summarise(signature = paste(val, collapse = ",")) %>% group_by(signature) %>% summarise(cols = list(col)) %>% pull(cols) # 查看分组结果 col_groups_tidy
这样就能完美实现你需要的分组和汇总啦!
内容的提问来源于stack exchange,提问作者Jasher
相关产品推荐
相关产品推荐

