【问题标题】:data.table way of complete+fill from tidyr with groups of difference length具有不同长度组的 tidyr 完成 + 填充的 data.table 方式
【发布时间】:2019-07-01 09:21:06
【问题描述】:

我有下面的例子。如何用data.table做同样的事情?

df <- data.frame(person = c(1,2,2),
                 observation_id = c(3,3,5),
                 value = c(1,1,1),
                 ind1 = c(2,4,4),
                 ind2 = c(5,7,7))

df %>% 
  group_by(person) %>% 
  tidyr::complete(observation_id = first(ind1):first(ind2), tidyr::nesting(person)) %>% 
  tidyr::fill(value)

预期输出:

# A tibble: 8 x 5
# Groups:   person [2]
  observation_id person value  ind1  ind2
           <dbl>  <dbl> <dbl> <dbl> <dbl>
1              2      1    NA    NA    NA
2              3      1     1     2     5
3              4      1     1    NA    NA
4              5      1     1    NA    NA
5              4      2    NA    NA    NA
6              5      2     1     4     7
7              6      2     1    NA    NA
8              7      2     1    NA    NA

谢谢你的建议!

【问题讨论】:

    标签: r data.table tidyverse


    【解决方案1】:

    这是原始的:

    DT <- setDT(copy(df))
    DT[DT[, .(observation_id = ind1[1]:ind2[1]), by = person], on = .(person, observation_id)
       ][, value := nafill(value, "locf"), by = person][]
    
    #    person observation_id value ind1 ind2
    # 1:      1              2    NA   NA   NA
    # 2:      1              3     1    2    5
    # 3:      1              4     1   NA   NA
    # 4:      1              5     1   NA   NA
    # 5:      2              4    NA   NA   NA
    # 6:      2              5     1    4    7
    # 7:      2              6     1   NA   NA
    # 8:      2              7     1   NA   NA
    

    注意 1:您(仍然)需要 development version of data.table 才能拥有 nafill()

    注意2:最后的[]只用于打印结果,可以跳过。

    【讨论】:

    • thx,有用的解决方案还有一个问题:如何进行多重填充?像这样 tidyr::fill(value, ind1, ind2)?
    • @jyjek,我对tidyr不是很熟悉,可能是lapply和.SDcols
    • nafill 处理列列表(或 data.table)以一次填充所有列,并在可能的情况下并行执行
    【解决方案2】:

    希望我正确解释了tidyverse 代码:

    library(data.table)
    setDT(df)
    df[df[, .(observation_id=seq(ind1[1L], ind2[1L])), by=.(person)], 
        on=.(person, observation_id)][,
            .(observation_id, value=zoo::na.locf(value, na.rm=FALSE), ind1, ind2), by=.(person)]
    

    使用 data.table 1.12.3,您可以使用 nafill 代替 zoo::na.locf

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-09
      • 2012-07-19
      • 1970-01-01
      • 2020-12-31
      • 1970-01-01
      • 1970-01-01
      • 2018-05-27
      • 2015-08-30
      相关资源
      最近更新 更多