【问题标题】:count adjacent NAs in data.frame column计算 data.frame 列中的相邻 NA
【发布时间】:2016-01-08 03:44:31
【问题描述】:

我喜欢添加一个额外的列“na_count”,用于计算列值中相邻的 NA,例如

value na_count
    8        0
    2        0 
   NA        4
   NA        4
   NA        4
   NA        4
    5        0
    9        0
    1        0
   NA        2
   NA        2 
    5        0
   NA        3
   NA        3
   NA        3
    8        0
    5        0
   NA        1

dplyr 窗口函数可能有办法吗?

【问题讨论】:

    标签: r dataframe dplyr data-manipulation


    【解决方案1】:

    这是一个使用dplyr 的选项(正如作者所要求的)。我们通过取逻辑向量的差 (!is.na(value)) 创建一个分组列,与 1 进行比较并执行 cumsum,然后通过将逻辑向量乘以组中的元素数 (n()) 创建“NA_count” )。

    library(dplyr)
    df1 %>% 
      select(-na_count) %>% #removing the column that was not needed
      group_by(grp=cumsum(c(TRUE,abs(diff(!is.na(value)))==1))) %>% 
      mutate(NA_count = is.na(value)*n()) %>%
      ungroup() %>%
      select(-grp)
    

    或者我们可以将'data.frame'转换为'data.table'(setDT(df1)),按逻辑向量(is.na(value))的rleid分组,我们得到nrow(.N),与逻辑向量相乘并提取“V1”列。

    library(data.table)#v1.9.6+
    setDT(df1)[, .N*is.na(value) ,rleid(is.na(value))]$V1
    #[1] 0 0 4 4 4 4 0 0 0 2 2 0 3 3 3 0 0 1
    

    如果这是创建一个新列,

    setDT(df1)[, Na_count:= .N*is.na(value) ,rleid(is.na(value))]
    

    或者我们可以使用来自base Rrle(运行长度编码)。我们在list 中获得'value' 的rle NA (is.na(df1$value)),使用within.list 更改'值',即TRUE 元素,将其用作相应'长度'的索引然后用inverse.rle返回原子向量。

    inverse.rle(within.list(rle(is.na(df1$value)),
                    {values[values] <- lengths[values] }))
    #[1] 0 0 4 4 4 4 0 0 0 2 2 0 3 3 3 0 0 1
    

    或者更紧凑的版本是

    inverse.rle(within.list(rle(is.na(df1$value)), values <-lengths*values))
    #[1] 0 0 4 4 4 4 0 0 0 2 2 0 3 3 3 0 0 1
    

    【讨论】:

    • 很酷,谢谢...愚蠢的是您不能接受两种解决方案...但这是我问题的确切答案,谢谢!
    【解决方案2】:

    不使用 dplyr,而是使用来自 base-R 的rle

    # get run-length of missings
    dd_rle <- rle(is.na(dd$value))
    
    # use rep: value is length if missing, 0 otherwise, number of repetitions
    # is length of runs
    # na_count2 so comparison to expected output possible
    dd$na_count2 <- rep(ifelse(dd_rle$values, dd_rle$lengths, 0),
                        dd_rle$lengths)
    

    【讨论】:

      猜你喜欢
      • 2019-08-04
      • 2017-04-22
      • 1970-01-01
      • 2015-07-28
      • 2013-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多