【问题标题】:How to use slice in dplyr to keep the rows with NA values in R如何在 dplyr 中使用切片来保留 R 中具有 NA 值的行
【发布时间】:2020-11-25 04:50:30
【问题描述】:

我有如下数据集,我想知道每组的最小词,如果没有最小词(是NA),我还想显示它

df=data.frame(
  key=c("A","A","B","B","C"),
  word=c(1,2,3,5,NA))

df%>%group_by(key)%>%slice(which.min(word))

这不包括我想要的 key=C, word=NA:

df_out=data.frame(
  key=c("A","B","C"),
  word=c(1,3,NA))

【问题讨论】:

    标签: r dplyr slice


    【解决方案1】:

    我们可以在filter 中使用is.na 创建一个逻辑条件,并在按'key' 进行分组后返回NA

    library(dplyr)
    df %>%
         group_by(key) %>% 
         filter(word == min(word)|is.na(word))
    

    或使用slice。我们不需要任何if/else 条件

    df %>%
        group_by(key) %>% 
        slice(which(word ==min(word)|is.na(word)))
    # A tibble: 3 x 2
    # Groups:   key [3]
    #  key    word
    #  <chr> <dbl>
    #1 A         1
    #2 B         3
    #3 C        NA
    

    或者更简洁

    df %>%
        group_by(key) %>% 
        slice(match(min(word), word))
    # A tibble: 3 x 2
    # Groups:   key [3]
    #  key    word
    #  <chr> <dbl>
    #1 A         1
    #2 B         3
    #3 C        NA
    

    注意:使用 match 返回第一个匹配项的索引。


    which.min 删除 NA

    which.min(c(NA, 1, 3))
    #[1] 2
    

    【讨论】:

      【解决方案2】:

      我们可以用if检查条件,如果all组中的wordNA我们返回第一行,否则返回最小行。

      library(dplyr)
      
      df %>%
        group_by(key)%>%
        slice(if(all(is.na(word))) 1L else which.min(word))
      
      # key    word
      #  <chr> <dbl>
      #1 A         1
      #2 B         3
      #3 C        NA
      

      另一种选择是arrangeword 的数据并选择每个组中的第一行。

      df %>% arrange(key, word) %>% group_by(key) %>% slice(1L)
      

      【讨论】:

        【解决方案3】:

        您还可以通过word 使用arrange 并使用dplyr 中的distinct 来获得所需的输出。

        library(dplyr)
        df %>% 
            arrange(word) %>% 
            distinct(key, .keep_all = TRUE)
        #  key word
        #1   A    1
        #2   B    3
        #3   C   NA
        

        【讨论】:

          【解决方案4】:

          您可以使用tidyverse-package 创建修改后的slice-function,它返回NA's:

          slice_uneven = function(.data, .idx) {
            .data_ = .data %>% add_row() # Add an extra row
            .idx_ = .idx %>% c(NA) %>% replace_na(nrow(.data_)) # Replace NA with index of the extra row
            .data_[.idx_,] %>% head(-1) %>% remove_rownames() %>% return() # Subset, remove extra row, and reset rownames before returning data
          }
          
          slice_uneven(cars, c(1, 2, 3, NA, NA, 3, 2))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-07-12
            • 1970-01-01
            • 1970-01-01
            • 2021-06-06
            • 2022-01-15
            • 1970-01-01
            • 2018-10-18
            • 1970-01-01
            相关资源
            最近更新 更多