Как добавить строки и экстраполировать данные по нескольким переменным? - PullRequest
2 голосов
/ 24 марта 2020

Я пытаюсь добавить пропущенные строки для «дня» и экстраполировать данные для «значения». В моих данных каждый субъект («id») имеет 2 периода (период 1 и период 2) и значения для последовательных дней.

Пример моих данных выглядит следующим образом:

df <- data.frame(
  id  =    c(1,1,1,1,  1,1,1,1,  2,2,2,2,  2,2,2,2,  3,3,3,3,  3,3,3,3),
  period = c(1,1,1,1,  2,2,2,2,  1,1,1,1,  2,2,2,2,  1,1,1,1,  2,2,2,2),
  day=     c(1,2,4,5,  1,3,4,5,  2,3,4,5,  1,2,3,5,  2,3,4,5,  1,2,3,4),
  value   =c(10,12,15,16, 11,14,15,17, 13,14,15,16, 15,16,18,20,  16,17,19,29, 14,16,18,20))

Для каждого идентификатора и периода я пропускаю данные за дни 3,2,1,4,1,5 соответственно. Я хочу расширить данные, скажем, до 10 дней, и экстраполировать данные по столбцу значений (например, с линейной регрессией).

Мой конечный df должен быть примерно таким:

df2 <- data.frame(
  id  =    c(1,1,1,1,1,1,1,         1,1,1,1,1,1,1,         2,2,2,2,2,2,2,        2,2,2,2,2,2,2,         3,3,3,3,3,3,3,         3,3,3,3,3,3,3),
  period = c(1,1,1,1,1,1,1,         2,2,2,2,2,2,2,         1,1,1,1,1,1,1,        2,2,2,2,2,2,2,         1,1,1,1,1,1,1,         2,2,2,2,2,2,2),
  day=     c(1,2,3,4,5,6,7,         1,2,3,4,5,6,7,         1,2,3,4,5,6,7,        1,2,3,4,5,6,7,         1,2,3,4,5,6,7,         1,2,3,4,5,6,7),
  value   =c(10,12,13,15,16,17,18,  11,12,14,15,17,18,19,  12,13,14,15,16,18,22, 15,16,18,19,20,22,23,  15,16,17,19,29,39,49,  14,16,18,20,22,24,26))

наиболее похожий пример , который я обнаружил, не экстраполирует на две переменные (ID и точка в моем случае), он экстраполирует только на год. Я попытался адаптировать код, но безуспешно: (

Другой пример экстраполирует данные по нескольким идентификаторам, но не добавляет строки для пропущенных данных.

Я не смог ' я могу объединить оба кода с моим ограниченным опытом в R. Есть предложения? Заранее спасибо ...

Ответы [ 2 ]

1 голос
/ 24 марта 2020

@ Ответ Акруна хорош, если вы не возражаете против использования линейной интерполяции. Однако, если вы хотите использовать линейную модель, вы можете попробовать этот метод data.table.

library(data.table)
model <- lm(value ~ day + period + id,data=df)
dt <- as.data.table(df)[,.SD[,.(day = 1:7,value = value[match(1:7,day)])],by=.(id,period)]
dt[is.na(value), value := predict(model,.SD),]
dt
    id period day    value
 1:  1      1   1 10.00000
 2:  1      1   2 12.00000
 3:  1      1   3 12.86714
 4:  1      1   4 15.00000
 5:  1      1   5 16.00000
 6:  1      1   6 18.13725
 7:  1      1   7 19.89396
 8:  1      2   1 11.00000
 9:  1      2   2 12.15545
10:  1      2   3 14.00000
11:  1      2   4 15.00000
12:  1      2   5 17.00000
13:  1      2   6 19.18227
14:  1      2   7 20.93898
15:  2      1   1 11.90102
16:  2      1   2 13.00000
17:  2      1   3 14.00000
18:  2      1   4 15.00000
19:  2      1   5 16.00000
20:  2      1   6 20.68455
21:  2      1   7 22.44125
22:  2      2   1 15.00000
23:  2      2   2 16.00000
24:  2      2   3 18.00000
25:  2      2   4 18.21616
26:  2      2   5 20.00000
27:  2      2   6 21.72957
28:  2      2   7 23.48627
29:  3      1   1 14.44831
30:  3      1   2 16.00000
31:  3      1   3 17.00000
32:  3      1   4 19.00000
33:  3      1   5 29.00000
34:  3      1   6 23.23184
35:  3      1   7 24.98855
36:  3      2   1 14.00000
37:  3      2   2 16.00000
38:  3      2   3 18.00000
39:  3      2   4 20.00000
40:  3      2   5 22.52016
41:  3      2   6 24.27686
42:  3      2   7 26.03357
    id period day    value
1 голос
/ 24 марта 2020

Мы можем использовать complete

library(dplyr)
library(tidyr)
library(forecast)
df %>% 
    group_by(id, period) %>% 
    complete(day =1:7)%>% 
    mutate(value = as.numeric(na.interp(value)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...