使用 R 如何删除基于多列的重复项,但选择重复项的“最完整”版本

Posted

技术标签:

【中文标题】使用 R 如何删除基于多列的重复项,但选择重复项的“最完整”版本【英文标题】:Using R how do I delete duplicates based on multiple columns but select the "most" completed version of the duplicates 【发布时间】:2020-11-19 20:39:02 【问题描述】:

我有一个脚本可以根据三列中的重复值进行删除。有超过三列,但我想根据这些特定的列删除

DF2021 <-DF2021 [!duplicated (DF2021[,c("column1","column2","column3")]),]

上面的脚本有效,每次根据这三列重复时,我都会留下一行。

下一步是我想知道如何确保我留下了基于标准的行。例如,我想要 NA 最少的行。

column1|column2|column3|column4|column5|column6|column 7
  Jan     Tue    2020   Blue    Warm  Hospital    NA
  Jan     Tue    2020   Blue    Warm     NA       NA
  Jan     Tue    2020   Blue    NA       NA       NA
  Feb     Thu    2020   Red     NA       NA       NA
  Feb     Thu    2020   Red     Warm     NA       NA
  Feb     Thu    2020   Red     Warm   Garden    Run
  Mar     Thu    2020   Red     Cold   Desk      Bus

最后,我希望重复值会留下三行。

column1|column2|column3|column4|column5|column6|column 7
Jan      Tue   2020    Blue    Warm   Hospital   NA
Feb      Thu   2020     Red    Warm   Garden    Run
Mar      Thu   2020     Red    Cold   Desk      Bus

请注意,如果我要这样做

DF2021 <- DF2021[complete.cases(DF2021),]

它只会给我 2 月和 3 月的行,而不是 1 月。我希望脚本删除重复项并根据这三行从重复项中取出“最多”行,但不必“完整”行.

【问题讨论】:

【参考方案1】:

试试这个。您可以创建一个函数来检测完整的行和只有一个NA 的行。有了它,您可以使用索引并选择该行。代码如下:

#Index for selection
myfun <- function(x)

  y <- length(which(is.na(x)))
  y <- ifelse(y<=1,1,0)
  return(y)

#Apply
index <- which(apply(df,1,myfun)==1)
#Output
out <- df[index,]

输出:

  column1 column2 column3 column4 column5  column6 column7
1     Jan     Tue    2020    Blue    Warm Hospital    <NA>
6     Feb     Thu    2020     Red    Warm   Garden     Run
7     Mar     Thu    2020     Red    Cold     Desk     Bus

【讨论】:

【参考方案2】:

您可以对数据框进行排序,使 NA 值位于最后,然后使用分组列进行重复数据删除:

DF2021[do.call(order, DF2021), ][!duplicated(DF2021[1:3]), ]

  column1 column2 column3 column4 column5  column6 column7
6     Feb     Thu    2020     Red    Warm   Garden     Run
1     Jan     Tue    2020    Blue    Warm Hospital    <NA>
7     Mar     Thu    2020     Red    Cold     Desk     Bus

如果您有大量列,则可以通过计算缺失数并按分组变量和缺失数对数据框进行排序来更有效地做到这一点:

DF2021$nmiss <- rowSums(is.na(DF2021[-(1:3)]))
DF2021 <- DF2021[do.call(order, DF2021[c(names(DF2021)[1:3], "nmiss")]), ][!duplicated(DF2021[1:3]), ]

如果您需要,请按原顺序退回:

DF2021[order(as.numeric(row.names(DF2021))), ]

  column1 column2 column3 column4 column5  column6 column7 nmiss
1     Jan     Tue    2020    Blue    Warm Hospital    <NA>     1
6     Feb     Thu    2020     Red    Warm   Garden     Run     0
7     Mar     Thu    2020     Red    Cold     Desk     Bus     0

【讨论】:

当我运行这个时,它删除了所有重复项,但它给我留下了 NA 最多的那个。我想要一个最少的。 您需要使用dput(DF2021) 提供数据样本。将其编辑到您的帖子中。

以上是关于使用 R 如何删除基于多列的重复项,但选择重复项的“最完整”版本的主要内容,如果未能解决你的问题,请参考以下文章

Excel:在多列中查找具有重复项的多个值

基于Javascript中的一列从多列中删除重复项

如何在不删除先前相同值的情况下选择具有重复项的列表中的特定数字?

删除数组中的重复项,但添加一个计数属性以查看重复项的数量

根据多列和日期时间删除重复项

如何使用条件连接选择重复项的表