【问题标题】:I have duplicate IDs in a data set, and would like to keep the one with the least amount of NAs across the data columns我在数据集中有重复的 ID,并希望在数据列中保留 NA 数量最少的 ID
【发布时间】:2021-05-17 06:38:26
【问题描述】:

我有一个具有重复 IDS 的数据框。我想保留 NA 数量最少的 ID(所以最完整的 ID 集)。在此示例中,我想保留第二个 123 和第二个 124(租赁 NA)

我可以识别重复项,但我无法编写代码来本质上说 1)对于每个副本,保留一个具有较少 NA 的副本 代码也可以说 2)对于每个重复,删除具有更多NA的那个,

这是示例数据

id    Col1    col1 2   col 3  col 4
123   10       NA       NA     3
123   50       3        2      NA
124   30       5        7      NA 
124   30       8        1      2

【问题讨论】:

    标签: r duplicates na


    【解决方案1】:

    您可以按每行中NAs 的数量进行排序,然后删除重复项:

    require(dplyr)
    df %>% arrange(rowSums(is.na(df))) %>% filter(!duplicated(id)) %>% arrange(id)
    
       id Col1 col2 col3 col4
    1 123   50    3    2   NA
    2 124   30    8    1    2
    

    数据:

    df = read.table(text='id Col1 col2 col3 col4
    123   10       NA       NA     3
    123   50       3        2      NA
    124   30       5        7      NA
    124   30       8        1      2', header = T, strip.white = T)
    

    【讨论】:

      【解决方案2】:
      library(data.table)
      setDT(df)
      
      df[order(rowSums(is.na(df))), head(.SD, 1), by = id]
      
      # id Col1 col2 col3 col4
      # 1: 124   30    8    1    2
      # 2: 123   50    3    2   NA
      

      【讨论】:

        【解决方案3】:

        我们可以使用slice

        library(dplyr)
        df %>% 
           group_by(id) %>%
           slice(which.min(rowSums(is.na(cur_data())))) %>%
           ungroup
        # A tibble: 2 x 5
        #     id  Col1  col2  col3  col4
        #  <int> <int> <int> <int> <int>
        #1   123    50     3     2    NA
        #2   124    30     8     1     2
        

        或使用c_across

        df %>%
          rowwise %>% 
          mutate(cnt = sum(is.na(c_across(-id)))) %>%
          ungroup %>% 
          arrange(id, cnt) %>%
          distinct(id, .keep_all = TRUE)
        

        数据

        df <- structure(list(id = c(123L, 123L, 124L, 124L), Col1 = c(10L, 
        50L, 30L, 30L), col2 = c(NA, 3L, 5L, 8L), col3 = c(NA, 2L, 7L, 
        1L), col4 = c(3L, NA, NA, 2L)), class = "data.frame", row.names = c(NA, 
        -4L))
        

        【讨论】:

        • 和第一个类似:df %&gt;% group_by(id) %&gt;% top_n(-1, rowSums(is.na(cur_data()))) %&gt;% ungroup
        猜你喜欢
        • 2020-10-27
        • 1970-01-01
        • 1970-01-01
        • 2021-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-24
        • 2020-09-08
        相关资源
        最近更新 更多