You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于数量未知的多列排除数据框中的重复行?

动态列去重:用distinct()处理除固定列外的所有列

问题背景

我有根据用户输入动态生成的数据框,示例如下:

df1 <- data.frame(A=c(1,2,1,4), 
                  B=c(4,3,4,1), 
                  C=c(3,2,3,4),
                  Y=c(2,7,6,3), 
                  Z=c(5,8,9,10))
df2 <- data.frame(A=c(1,2,1,4),
                  B=c(4,3,4,1), 
                  C=c(3,2,3,4),
                  D=c(2,1,2,3),
                  Y=c(2,7,6,3), 
                  Z=c(5,8,9,10))

df2里第3行的A、B、C、D列和第1行完全重复。常规去重写法需要手动指定列:

library(dplyr)
df1 |> distinct(A,B,C, .keep_all=TRUE)
df2 |> distinct(A,B,C,D, .keep_all=TRUE)

但问题是,除了固定的Y、Z列,其余列的数量和名称不固定(可能是A、B两列,也可能是A到F列)。我尝试过先提取列名再传入distinct(),但程序会把列名向量当成列名本身,导致报错:

names <- colnames(df2)
names <- names[names != c("Y", "Z")]
df2 |> distinct(names, .keep_all=TRUE) # 错误:找不到名为"names"的列

解决方法

这里有两种简洁的方式实现针对Y、Z之外所有列的动态去重:

方法1:用all_of()解析列名向量

先通过setdiff()获取除Y、Z外的列名(比直接用!=更稳妥,避免多列排除时的匹配问题),再用all_of()把字符向量解析为数据框的列:

library(dplyr)

# 获取目标列名
target_cols <- setdiff(colnames(df2), c("Y", "Z"))

# 动态去重
df2 |> distinct(all_of(target_cols), .keep_all = TRUE)

方法2:用across()直接排除固定列

无需手动生成列名向量,直接用across(-c(Y, Z))选择除Y、Z外的所有列:

df2 |> distinct(across(-c(Y, Z)), .keep_all = TRUE)

这种写法更简洁,适合快速实现需求。

效果验证

执行上述代码后,df2会被去重,移除重复的第3行,结果如下:

A B C D Y  Z
1 1 4 3 2 2  5
2 2 3 2 1 7  8
4 4 1 4 3 3 10

内容的提问来源于stack exchange,提问作者tlmoore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 12:00:22