【问题标题】:R - filter row if id column is unique or, when id is duplicated, the row with least NAsR - 如果 id 列是唯一的,则过滤行,或者当 id 重复时,NAs 最少的行
【发布时间】:2018-04-10 18:41:00
【问题描述】:

我有一个这样的数据框:

set.seed(123)

testdf <- data.frame(id = c(123,124,125,125,126,126,126,127,128,129,130),
                 var01 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var02 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var03 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var04 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var05 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var06 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var07 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var08 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var09 = c(sample(c("A", "B", "C", NA), 11, TRUE)),
                 var10  = c(sample(c("A", "B", "C", NA), 11, TRUE)))

testdf
    id var01 var02 var03 var04 var05 var06 var07 var08 var09 var10
1  123     B     B     C  <NA>     A     A  <NA>     C  <NA>     C
2  124  <NA>     C  <NA>     A     A     A  <NA>     B     A     C
3  125     B     C     C     B     A  <NA>  <NA>     A     A     B
4  125  <NA>     A     C  <NA>     B  <NA>     B     A     C     B
5  126  <NA>  <NA>     C     A     B     B  <NA>     C     B  <NA>
6  126     A     A     C     B  <NA>     C     C     B     C     B
7  126     C     A     B     A     A     A     C  <NA>     B  <NA>
8  127  <NA>     B     A     A     B     B     A     A     A  <NA>
9  128     C  <NA>  <NA>     B  <NA>     B     B     B  <NA>     C
10 129     B  <NA>  <NA>     B     A  <NA>     A  <NA>     A     B
11 130  <NA>     C     C     B     C     B     B  <NA>     B     A

我想根据 2 个条件过滤行:

1) 具有唯一 ID 的行。

2)当ID重复时,我想保留该行中NAs最少的行。

我想要的输出存在于除 4、5 和 7 之外的所有行。 您可以假设每个 id 的行中的最小 NA 仅出现一次(因此 2 代表 id 125,1 代表 126)。

我更喜欢基本的 R 或 dplyr 解决方案。

非常感谢。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:
    library(dplyr)
    testdf %>% 
      mutate(NAs = rowSums(is.na(.))) %>% 
      group_by(id) %>% 
      filter(NAs == min(NAs)) %>% 
      select(-NAs) %>% 
      ungroup
    

    或者

    testdf %>% 
      arrange(id, rowSums(is.na(.))) %>% 
      group_by(id) %>% 
      slice(1) %>% 
      ungroup 
    

    【讨论】:

    • @Renu 出于好奇,如果您至少有任何关系怎么办?我想,这个选择可能是主观的。
    • 添加%&gt;% slice(1)
    【解决方案2】:

    我注意到我几年前问过这个问题,当时我对 R 的经验较少。如果它对任何人有用,这可能是最短的解决方案:

    testdf %>% 
      arrange(id, rowSums(is.na(.))) %>% 
      distinct(id, .keep_all = T)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多