【问题标题】:Remove semi duplicate rows in R删除 R 中的半重复行
【发布时间】:2017-03-21 06:04:06
【问题描述】:

我有以下data.frame。

a <- c(rep("A", 3), rep("B", 3), rep("C",2), "D")
b <- c(NA,1,2,4,1,NA,2,NA,NA)
c <- c(1,1,2,4,1,1,2,2,2)
d <- c(1,2,3,4,5,6,7,8,9)
df <-data.frame(a,b,c,d)


  a  b c d
1 A NA 1 1
2 A  1 1 2
3 A  2 2 3
4 B  4 4 4
5 B  1 1 5
6 B NA 1 6
7 C  2 2 7
8 C NA 2 8
9 D NA 2 9

我想删除重复的行(基于 A 列和 C 列),以便保留 B 列中具有值的行。在此示例中,删除了第 1、6 和 8 行。

【问题讨论】:

  • 不完全。这将删除第 5 行和第 6 行并删除第 2 行而不是第 1 行。

标签: r


【解决方案1】:

这样做的一种方法是 order 通过 'a'、'b' 和基于 'b' 的逻辑向量,这样所有 'NA' 元素将在每组 'a' 的最后一个,并且'b'。然后,应用duplicated 并只保留非重复元素

df1 <- df[order(df$a, df$b, is.na(df$b)),]
df2 <- df1[!duplicated(df1[c('a', 'c')]),]
df2
#  a  b c d
#2 A  1 1 2
#3 A  2 2 3
#5 B  1 1 5
#4 B  4 4 4
#7 C  2 2 7
#9 D NA 2 9

setdiff(seq_len(nrow(df)), row.names(df2) )
#[1] 1 6 8

【讨论】:

  • 这行得通。订单功能中is.na(df$b)的作用是什么?删除后我试了一下,df2是一样的。
  • @Stephen 我刚刚用描述更新了帖子。这是为了确保每个'a','b'对的NA元素都是最后的
【解决方案2】:

首先使用以下函数创建两个数据集,一个在 a 列中有重复,一个在 a 列中没有重复:

x = df[df$a %in% names(which(table(df$a) > 1)), ]
x1 = df[df$a %in% names(which(table(df$a) ==1)), ]

现在对数据集 x 使用 na.omit 函数删除具有 NA 的行,然后将 x 和 x1 rbind 到最终数据集。

rbind(na.omit(x),x1)

答案:

   a  b c d

2  A  1 1 2

3  A  2 2 3

4  B  4 4 4

5  B  1 1 5

7  C  2 2 7

9  D NA 2 9

【讨论】:

    【解决方案3】:

    您可以使用dplyr 来执行此操作。

    df %>% distinct(a, c,  .keep_all = TRUE)                 
    

    输出

      a  b c d
    1 A NA 1 1
    2 A  2 2 3
    3 B  4 4 4
    4 B  1 1 5
    5 C  2 2 7
    6 D NA 2 9
    

    dplyr还有其他选项,详情查看这个问题:Remove duplicated rows using dplyr

    【讨论】:

      猜你喜欢
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      • 2015-01-19
      • 2020-04-23
      • 1970-01-01
      • 2021-05-22
      • 2016-01-09
      相关资源
      最近更新 更多