如何在DataFrame中仅保留每行的唯一值?
解决DataFrame逐行保留唯一值的问题
我懂你遇到的问题了——你要的是对DataFrame的每一行单独去重,但之前用plyr和全局unique()的思路是对整个数据集去重,完全没达到逐行处理的效果对吧?
方法1:基础的apply逐行处理
这是最直接的方式,用apply()按行遍历,对每行单独调用unique(),同时可以先过滤掉NA值(如果你的数据里有空值的话):
# 假设你的数据框名为df # 逐行提取唯一值,过滤NA,最后转置成行结构 result <- t(apply(df, 1, function(row) unique(row[!is.na(row)])))
举个例子,用你提供的输入数据:
# 构造输入数据框 df <- data.frame( col1 = c(1,1,2,0,5), col2 = c(1,6,2,0,1), col3 = c(2,7,5,6,2), col4 = c(3,8,5,6,3), col5 = c(4,NA,7,6,4), col6 = c(NA,NA,8,6,NA), col7 = c(NA,NA,9,NA,NA) )
运行上面的代码后,输出就和你期望的一致(长度不足的行会自动补NA,如果你想去掉NA可以后续再处理)。
方法2:用dplyr的行级处理(更符合tidyverse风格)
如果你习惯用tidyverse工具链,可以结合rowwise()和c_across()来实现:
library(dplyr) library(tidyr) result <- df %>% rowwise() %>% # 把每行的所有列合并,提取唯一值,存为列表列 mutate(unique_vals = list(unique(c_across(everything())))) %>% ungroup() %>% # 把列表列展开成宽格式(长度不足的补NA) unnest_wider(unique_vals, names_sep = "_")
这个方法的好处是可以和其他tidyverse操作无缝衔接,比如后续还要对去重后的数据做处理。
为什么之前的方法没用?
- 全局
unique(df)是对整个数据框的行去重——也就是保留那些完全不重复的行,而不是每行内部的元素去重。 plyr的函数大多是按分组处理数据,默认不会逐行对元素去重,所以达不到你的需求。
内容的提问来源于stack exchange,提问作者Praveen M Kulkarni
相关产品推荐
相关产品推荐

