Как ЭКСТРАПОЛИРОВАТЬ отсутствующие данные с помощью R в панельных данных?

В панельных данных у меня есть некоторые значения NA, которые я хотел бы экстраполировать на конец или начало интересующих меня лет. Большинство решений подобных вопросов связаны с интерполяцией. Обратите внимание, что это не так.

Аналогичный образец моих данных, называемый данными, выглядит так:

> data
   REGION YEAR  VALUE
1       A 2011     NA
2       A 2012     NA
3       A 2013     NA
4       A 2014  20.00
5       A 2015  25.00
6       A 2016  30.00
7       A 2017  35.00
8       A 2018  40.00
9       B 2011     NA
10      B 2012   0.30
11      B 2013   0.50
12      B 2014   0.70
13      B 2015   0.90
14      B 2016   0.11
15      B 2017   0.13
16      B 2018   0.15
17      C 2011 100.00
18      C 2012 101.00
19      C 2013 102.00
20      C 2014 103.00
21      C 2015 104.00
22      C 2016 105.00
23      C 2017 106.00
24      C 2018     NA

Некоторые решения, которые я нашел для подобных вопросов:

Я пробовал с na_interpolate, но он просто повторяет последние значения. Я также пробовал с mutate в сочетании с na.spline, но это создает значения, которые явно неверны для линейной регрессии.

Я уверен, что должен быть простой способ оценить эти значения.

Ожидаемый результат должен выглядеть так:

> data
   REGION YEAR  VALUE
1       A 2011   5.00
2       A 2012  10.00
3       A 2013  15.00
4       A 2014  20.00
5       A 2015  25.00
6       A 2016  30.00
7       A 2017  35.00
8       A 2018  40.00
9       B 2011   0.10
10      B 2012   0.30
11      B 2013   0.50
12      B 2014   0.70
13      B 2015   0.90
14      B 2016   0.11
15      B 2017   0.13
16      B 2018   0.15
17      C 2011 100.00
18      C 2012 101.00
19      C 2013 102.00
20      C 2014 103.00
21      C 2015 104.00
22      C 2016 105.00
23      C 2017 106.00
24      C 2018 107.00

спасибо за помощь


person jpparraguez    schedule 06.07.2020    source источник
comment
Вы сделали опечатку в REGION B для YEAR 2016 - 2018?   -  person Edward    schedule 06.07.2020


Ответы (2)


Вы можете просто сделать:

predictions <- round(predict(lm(VALUE ~ REGION * YEAR, df), newdata = df), 2)
predictions
#>      1      2      3      4      5      6      7      8      9     10 
#>   5.00  10.00  15.00  20.00  25.00  30.00  35.00  40.00   0.65   0.59 
#>     11     12     13     14     15     16     17     18     19     20 
#>   0.53   0.46   0.40   0.34   0.27   0.21 100.00 101.00 102.00 103.00 
#>     21     22     23     24 
#> 104.00 105.00 106.00 107.00 

df$VALUE[is.na(df$VALUE)] <- predictions[is.na(df$VALUE)]

Что дает желаемый результат:

df
#>    REGION YEAR  VALUE
#> 1       A 2011   5.00
#> 2       A 2012  10.00
#> 3       A 2013  15.00
#> 4       A 2014  20.00
#> 5       A 2015  25.00
#> 6       A 2016  30.00
#> 7       A 2017  35.00
#> 8       A 2018  40.00
#> 9       B 2011   0.65
#> 10      B 2012   0.30
#> 11      B 2013   0.50
#> 12      B 2014   0.70
#> 13      B 2015   0.90
#> 14      B 2016   0.11
#> 15      B 2017   0.13
#> 16      B 2018   0.15
#> 17      C 2011 100.00
#> 18      C 2012 101.00
#> 19      C 2013 102.00
#> 20      C 2014 103.00
#> 21      C 2015 104.00
#> 22      C 2016 105.00
#> 23      C 2017 106.00
#> 24      C 2018 107.00
person Allan Cameron    schedule 06.07.2020
comment
Спасибо! это работает, хотя это немного медленно для моего компьютера, учитывая, что мой df имеет более 10 000 наблюдений, и мне нужно сделать это для 15 различных переменных. Я думаю, мне нужно немного терпения - person jpparraguez; 07.07.2020

Для линейной экстраполяции вы можете подобрать линейную модель, а затем использовать predict.

data$VALUE[is.na(data$VALUE)] <- unlist(lapply(split(data, data$REGION), 
FUN=function(x) predict(lm(VALUE~YEAR, data=x), newdata=subset(x, subset=is.na(VALUE)))))

И я думаю, что вы сделали опечатку для REGION B.


Данные:

data <- structure(list(REGION = c("A", "A", "A", "A", "A", "A", "A", 
"A", "B", "B", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", 
"C", "C", "C", "C"), YEAR = c(2011L, 2012L, 2013L, 2014L, 2015L, 
2016L, 2017L, 2018L, 2011L, 2012L, 2013L, 2014L, 2015L, 2016L, 
2017L, 2018L, 2011L, 2012L, 2013L, 2014L, 2015L, 2016L, 2017L, 
2018L), VALUE = c(NA, NA, NA, 
20, 25, 30, 35, 40, NA, 0.3, 0.5, 0.7, 0.9, 1.1, 
1.3, 1.5, 100, 101, 102, 103, 104, 105, 106, NA)), row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"
), class = "data.frame")
person Edward    schedule 06.07.2020
comment
Могу я спросить, почему вы делаете три разные регрессии вместо одной с интерактивным термином? Разве это не более сложный способ получения того же результата? - person Allan Cameron; 06.07.2020
comment
@ Аллан Кэмерон. Хороший вопрос. Ваше решение с использованием взаимодействия намного проще. Вы получили мой голос! - person Edward; 06.07.2020