【问题标题】:R: How to remove duplicates with some conditions in a complex Dataframe?R:如何在复杂的数据框中删除具有某些条件的重复项?
【发布时间】:2020-02-13 22:28:43
【问题描述】:

我有一个工厂生产金银产品(笔)的数据集,我们想通过分配员工检查工厂所有机器生产的这些产品来检查质量。数据样本数据如下:

每台机器都位于特定的房间/区域/建筑物中,我们有两列来对测试金笔和银笔的员工 ID 进行分组。

问题是我有重复的员工测试同一台机器的质量。所以我想删除这些重复项并将那些不重复的分组。 示例:

Bld.No <- c(1,1,1,1,1,1,2,2,2,2)
Section <- c("A","A","A","A","B","B","C","C","D","D")
Room.No <- c(100,100,100,100,200,200,300,300,400,400)
Gold <- c(8,6,4,0,6,0,7,2,2,1)
Silver <- c(1,0,0,1,2,3,4,0,4,0)
Total <- c(9,6,4,1,8,3,11,2,6,1)
Emp.Gold.ID <- c("A11, A09, B22, E12, A04, C09, D33, A01", "A11, A09, B22, E12, A04, A01", "A09, 822, E12, A04", NA, "A71, A09, B12, E32, A04, C19", NA, "B22, E12, A04, C09, D33, A01, M11", "E12, Z09", "C09, D33", "D18")
Emp.Silver.ID <- c("A17", NA, NA, "D33", "B22, E12", "A09, B12, E32", "A44, C02, D03, A71", NA, "A12, A01, M11, D18", NA)

df <- data.frame(Bld.No, Section, Room.No, Gold, Silver, Total, Emp.Gold.ID, Emp.Silver.ID)

注意:如果 emp.Id 已经在之前的记录中,无论是金还是银,我们都应该删除它。这意味着 ID 应该在其中一个中并删除重复项。看sample and output表最后一条记录的例子,我们去掉了最后一条记录(2,D,400,1,0,1,D18,NA),因为D18已经在上一条记录中了,虽然它是在银列。

样本数据和输出:

Sample Data and Output

【问题讨论】:

    标签: r dataframe duplicates


    【解决方案1】:

    为此,我将使用 separate_rows 将所有 ID 放在单独的行中,以便稍后使用 distinct 删除重复项。

    删除重复 ID 后,将为黄金和白银创建以逗号分隔的 ID 字符串。您可以在此步骤之前或之后汇总总金和银。

    请注意,为了获得与示例数据和输出中相同的结果,我将 822 更改为 B22

    如果这是您的想法,请告诉我。

    library(dplyr)
    library(tidyr)
    
    df$Emp.Gold.ID <- as.character(df$Emp.Gold.ID)
    df$Emp.Silver.ID <- as.character(df$Emp.Silver.ID)
    
    df %>% 
      separate_rows(Emp.Gold.ID) %>%
      separate_rows(Emp.Silver.ID) %>%
      pivot_longer(cols = starts_with("Emp."), names_to = "ID", values_drop_na = TRUE) %>%
      group_by(Bld.No, Section, Room.No) %>%
      distinct(value, .keep_all = TRUE) %>%
      group_by(Bld.No, Section, Room.No, ID) %>%
      summarise(NewID = toString(value)) %>%
      pivot_wider(names_from = ID, values_from = NewID) %>%
      mutate(Gold = length(unlist(strsplit(Emp.Gold.ID, ", "))),
             Silver = length(unlist(strsplit(Emp.Silver.ID, ", "))),
             Total = Gold + Silver)
    
    # A tibble: 4 x 8
    # Groups:   Bld.No, Section, Room.No [8]
      Bld.No Section Room.No Emp.Gold.ID                            Emp.Silver.ID       Gold Silver Total
       <dbl> <fct>     <dbl> <chr>                                  <chr>              <int>  <int> <int>
    1      1 A           100 A11, A09, B22, E12, A04, C09, D33, A01 A17                    8      1     9
    2      1 B           200 A71, A09, B12, E32, A04, C19           B22, E12               6      2     8
    3      2 C           300 B22, E12, A04, C09, D33, A01, M11, Z09 A44, C02, D03, A71     8      4    12
    4      2 D           400 C09, D33                               A12, A01, M11, D18     2      4     6
    

    【讨论】:

    • 感谢 Ben 付出的时间和精力,它工作得很好。唯一的问题是运行它需要很长时间才能处理大量数据。
    猜你喜欢
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    相关资源
    最近更新 更多