【问题标题】:Find duplicated elements with dplyr使用 dplyr 查找重复元素
【发布时间】:2015-03-30 09:57:15
【问题描述】:

我尝试使用here 提供的代码来查找带有dplyr 的所有重复元素,如下所示:

library(dplyr)

mtcars %>%
mutate(cyl.dup = cyl[duplicated(cyl) | duplicated(cyl, from.last = TRUE)])

如何转换here 提供的代码以查找所有带有dplyr 的重复元素?我上面的代码只是抛出一个错误?或者更好的是,有没有比复杂的x[duplicated(x) | duplicated(x, from.last = TRUE)]) 方法更简洁地实现这一点的另一个函数?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我想你可以使用 filter 来达到这个目的:

    mtcars %>% 
      group_by(carb) %>% 
      filter(n()>1)
    

    小例子(请注意,我添加了summarize() 以证明生成的数据集不包含具有重复'carb'的行。我使用'carb'而不是'cyl',因为'carb'具有唯一值而'cyl ' 没有):

    mtcars %>% group_by(carb) %>% summarize(n=n())
    #Source: local data frame [6 x 2]
    #
    #  carb  n
    #1    1  7
    #2    2 10
    #3    3  3
    #4    4 10
    #5    6  1
    #6    8  1
    
    mtcars %>% group_by(carb) %>% filter(n()>1) %>% summarize(n=n())
    #Source: local data frame [4 x 2]
    #
    #  carb  n
    #1    1  7
    #2    2 10
    #3    3  3
    #4    4 10
    

    【讨论】:

    • 我还提到了 add_count 函数,它添加了 n 列,然后我们可以对其进行过滤:mtcars %>% add_count(carb) %>% filter(n>1) 与附加的 n 列给出相同的结果。
    【解决方案2】:

    另一种解决方案是使用janitorpackage

    mtcars %>% get_dupes(wt)
    

    【讨论】:

    • 请注意,这样做的结果包含数据中的所有重复实例。例如,如果您运行get_dupes(data.frame(x=c(1,1,1))),您将获得整个 df。 get_dupes 还添加了一列计数。见here
    【解决方案3】:

    我们可以使用 dplyr 找到重复的元素,如下所示。

    library(dplyr)
    
    # Only duplicated elements
    mtcars %>%
      filter(duplicated(.[["carb"]])
    
    # All duplicated elements
    mtcars %>%
      filter(carb %in% unique(.[["carb"]][duplicated(.[["carb"]])]))
    

    【讨论】:

    • 还有下面的多列语法mtcars %>% filter(duplicated(.[c("carb", "cyl")])
    【解决方案4】:

    原帖在使用related answer 的解决方案时出现错误。在给出的示例中,当您在 mutate 中使用该解决方案时,它会尝试对 cyl 向量进行子集化,该向量的长度与 mtcars 数据帧的长度不同。

    相反,您可以使用以下示例与过滤器返回所有重复的元素或使用 ifelse 进行变异以创建一个可以稍后过滤的虚拟变量:

     library(dplyr)
    
     # Return all duplicated elements
     mtcars %>%
       filter(duplicated(cyl) | duplicated(cyl, fromLast = TRUE))
     # Or for making dummy variable of all duplicated
     mtcars %>%
       mutate(cyl.dup =ifelse(duplicated(cyl) | duplicated(cyl, fromLast = TRUE), 1,0))
    

    【讨论】:

      【解决方案5】:
      # Adding a shortcut to the answer above
      library(dplyr)
      #> 
      #> Attaching package: 'dplyr'
      #> The following objects are masked from 'package:stats':
      #> 
      #>     filter, lag
      #> The following objects are masked from 'package:base':
      #> 
      #>     intersect, setdiff, setequal, union
      mtcars %>% count(carb)
      #> # A tibble: 6 x 2
      #>    carb     n
      #>   <dbl> <int>
      #> 1    1.     7
      #> 2    2.    10
      #> 3    3.     3
      #> 4    4.    10
      #> 5    6.     1
      #> 6    8.     1
      mtcars %>% count(carb) %>% filter(n > 1)
      #> # A tibble: 4 x 2
      #>    carb     n
      #>   <dbl> <int>
      #> 1    1.     7
      #> 2    2.    10
      #> 3    3.     3
      #> 4    4.    10
      
      # Showing an alternative that follows the apparent intention if the asker
      duplicated_carb <- mtcars %>% 
        mutate(dup_carb = duplicated(carb)) %>% 
        filter(dup_carb)
      duplicated_carb
      #>     mpg cyl  disp  hp drat    wt  qsec vs am gear carb dup_carb
      #> 1  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4     TRUE
      #> 2  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1     TRUE
      #> 3  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1     TRUE
      #> 4  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4     TRUE
      #> 5  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2     TRUE
      #> 6  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2     TRUE
      #> 7  19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4     TRUE
      #> 8  17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4     TRUE
      #> 9  17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3     TRUE
      #> 10 15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3     TRUE
      #> 11 10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4     TRUE
      #> 12 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4     TRUE
      #> 13 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4     TRUE
      #> 14 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1     TRUE
      #> 15 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2     TRUE
      #> 16 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1     TRUE
      #> 17 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1     TRUE
      #> 18 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2     TRUE
      #> 19 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2     TRUE
      #> 20 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4     TRUE
      #> 21 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2     TRUE
      #> 22 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1     TRUE
      #> 23 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2     TRUE
      #> 24 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2     TRUE
      #> 25 15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4     TRUE
      #> 26 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2     TRUE
      

      【讨论】:

      • 作为“替代方案”,Marat 的答案有 30 行,而您的有 26 行。我想您可以改为在原始管道中添加一个步骤:mtcars %&gt;% count(carb) %&gt;% filter(n &gt; 1) %&gt;% left_join(mtcars) 可能首先使用 select(-n)。
      【解决方案6】:

      您可以使用 duplicated() 创建布尔掩码:

      iris %>% duplicated()
        [1] FALSE FALSE FALSE .... TRUE FALSE
      [145] FALSE FALSE FALSE FALSE FALSE FALSE
      

      并通过方括号进行索引:

      iris[iris %>% duplicated(),]
          Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
      143          5.8         2.7          5.1         1.9 virginica
      

      注意:这种方法最接近 Pandas 这可以用 R 和 dplyr 完成:

      iris[iris %>% duplicated(), c("Petal.Length","Petal.Width","Species")]
          Petal.Length Petal.Width   Species
      143          5.1         1.9 virginica
      

      【讨论】:

        【解决方案7】:

        在具有列的数据框中查找重复值

        df<-dataset[duplicated(dataset$columnname),]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-18
          • 2010-09-14
          • 1970-01-01
          • 1970-01-01
          • 2015-02-24
          • 2016-10-05
          相关资源
          最近更新 更多