data.table способ завершения + заливка из тидыра группами разной длины - PullRequest
0 голосов
/ 01 июля 2019

У меня есть пример ниже.Как сделать то же самое с 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

Спасибо за совет!

Ответы [ 2 ]

3 голосов
/ 01 июля 2019

Вот что-то сырое:

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: вам (все еще) нужна версия для разработки data.table, чтобы иметь nafill().

Примечание 2: окончательный [] предназначен только для печати результатов и может быть пропущен.

1 голос
/ 01 июля 2019

Надеюсь, я правильно интерпретировал код 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

...