R: Заполните неявные пропущенные значения и группы за весь промежуток времени данных - PullRequest
2 голосов
/ 12 октября 2019

Цель : заполнить неявные пропущенные значения для каждого идентификатора и каждой группы за весь промежуток времени данных, включая групп, которые полностью отсутствуют из набора данных.

Фон : у каждого идентификатора есть несколько групп, и у каждой группы должны быть значения для каждого дня. Однако в некоторых значениях отсутствуют определенные даты (например, 1b 2019-01-01), а в некоторых группах полностью отсутствует из набора данных (например, 2b).

# A tibble: 8 x 4
     ID group date       value
  <dbl> <chr> <chr>      <dbl>
1     1 a     2019-01-01     1
2     1 a     2019-01-02     3
3     1 a     2019-01-03     4
4     1 b     2019-01-02     4
5     1 b     2019-01-03     5
6     2 a     2019-01-01     8
7     2 a     2019-01-02     9
8     2 a     2019-01-03     1

Код для генерации кадра данных

df <- tibble(ID = c(1, 1, 1, 1, 1, 2, 2, 2),
             group = c('a', 'a', 'a', 'b', 'b', 'a', 'a', 'a'),
             date = c('2019-01-01', '2019-01-02','2019-01-03', '2019-01-02', '2019-01-03', '2019-01-01', '2019-01-02', '2019-01-03'),
             value = c(1, 3, 4, 4, 5, 8, 9, 1))

Попытка 1:

library(tsibble)
df %>% 
  # tsibble format
  as_tsibble(key = c(ID, group), index = date) %>%
  # group by
  group_by(ID, group) %>%
  # fill gaps
  fill_gaps(.full = TRUE)

Попытка 2:

library(tidyverse)
complete(df, expand(df, nesting(ID, group), date = full_seq(date,1)))

Оба даюттот же результат: обратите внимание, что группа 2b отсутствует

# A tsibble: 9 x 4 [1D]
# Key:       ID, group [3]
# Groups:    ID, group [3]
     ID group date       value
  <dbl> <chr> <date>     <dbl>
1     1 a     2019-01-01     1
2     1 a     2019-01-02     3
3     1 a     2019-01-03     4
4     1 b     2019-01-01    NA
5     1 b     2019-01-02     4
6     1 b     2019-01-03     5
7     2 a     2019-01-01     8
8     2 a     2019-01-02     9
9     2 a     2019-01-03     1

Я ожидаю, что на выходе будет

# A tibble: 12 x 4
      ID group date       value
   <dbl> <chr> <chr>      <dbl>
 1     1 a     2019-01-01     1
 2     1 a     2019-01-02     3
 3     1 a     2019-01-03     4
 4     1 b     2019-01-01     NA
 5     1 b     2019-01-02     4
 6     1 b     2019-01-03     5
 7     2 a     2019-01-01     8
 8     2 a     2019-01-02     9
 9     2 a     2019-01-03     1
10     2 b     2019-01-01     NA
11     2 b     2019-01-02     NA
12     2 b     2019-01-03     NA

, где группаb , который неявно пропускает из набора данных, появляется в результате.

Обратите внимание, что мой набор данных содержит восемь миллионов строк и продолжает расти каждый день. Код будет выполняться каждый день, поэтому я с нетерпением жду быстрого запуска 1044 * и удобного способа выполнения задачи. Но любая идея или ответ приветствуется!

Ответы [ 2 ]

2 голосов
/ 13 октября 2019

На самом деле ваша вторая попытка очень близка к ожидаемой, но нужно заменить nesting() на crossing(). nesting() ищет только комбинации, появившиеся в данных, но crossing() ищет все возможные комбинации.

library(tidyr)
df <- tibble(ID = c(1, 1, 1, 1, 1, 2, 2, 2),
             group = c('a', 'a', 'a', 'b', 'b', 'a', 'a', 'a'),
             date = as.Date(c('2019-01-01', '2019-01-02','2019-01-03', '2019-01-02', '2019-01-03', '2019-01-01', '2019-01-02', '2019-01-03')),
             value = c(1, 3, 4, 4, 5, 8, 9, 1))
complete(df, expand(df, crossing(ID, group), date = full_seq(date, 1)))
#> # A tibble: 12 x 4
#>       ID group date       value
#>    <dbl> <chr> <date>     <dbl>
#>  1     1 a     2019-01-01     1
#>  2     1 a     2019-01-02     3
#>  3     1 a     2019-01-03     4
#>  4     1 b     2019-01-01    NA
#>  5     1 b     2019-01-02     4
#>  6     1 b     2019-01-03     5
#>  7     2 a     2019-01-01     8
#>  8     2 a     2019-01-02     9
#>  9     2 a     2019-01-03     1
#> 10     2 b     2019-01-01    NA
#> 11     2 b     2019-01-02    NA
#> 12     2 b     2019-01-03    NA

Создано в 2019-10-13 пакетом представ. (v0.3.0)

1 голос
/ 12 октября 2019

Вы можете создать фрейм данных, содержащий декартово произведение уникальных значений ID, группы и даты, а затем объединить его с оригинальным фреймом данных для получения желаемого результата.

zz <- merge(merge(unique(df$ID), unique(df$group), by = NULL, all = TRUE), 
            unique(df$date), by = NULL, all = TRUE)
merge(df, zz, by.x = c('ID','group', 'date'), by.y = c('x','y.x', 'y.y'), all = TRUE)

Это дорого, конечно,если у вас есть большое количество компонентов и дат. В этом случае вы можете сначала объединить комбинацию ID / группы с исходным кадром данных, чтобы получить только пропущенные комбинации, а затем объединить ее с набором дат, снова выбирая только пропущенные комбинации, если вы поймете мой дрейф.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...