Как интерполировать / экстраполировать, используя функцию na.approx в отдельных группах в R
У меня есть набор данных панели с 10 переменными для 60 стран за 18 лет (2000-2017), и у меня много пропущенных данных.
Country Year Broadband
Albania 2000 NA
Albania 2001 NA
Albania 2002 NA
Albania 2003 NA
Albania 2004 NA
Albania 2005 272
Albania 2006 NA
Albania 2007 10000
Albania 2008 64000
Albania 2009 92000
Albania 2010 105539
Albania 2011 128210
Albania 2012 160088
Albania 2013 182556
Albania 2014 207931
Albania 2015 242870
Albania 2016 263874
Albania 2017 NA
Algeria 2000 NA
Algeria 2001 NA
Algeria 2002 NA
Algeria 2003 18000
Algeria 2004 36000
Я хотел бы интерполировать, используя функцию na.approx в R (и экстраполировать, используя правило = 2), но только внутри каждой страны. Например, в этом примере набора данных я хочу интерполировать значение для Албании 2006 и экстраполировать для Албании 2000-2004 и 2017 гг. Но я хочу убедиться, что значение для Албании 2017 не интерполируется с использованием Албании 2016 и Алжира 2003. Для Алжира 2000-2002 гг. Я хочу, чтобы значения были экстраполированы с использованием данных для Алжира 2003 и 2004 гг. Я попробовал следующий код:
data <- group_by(data, country)
data$broadband <- na.approx(data$broadband, maxgap = Inf, rule = 2)
data <- as.data.frame(data)
и пробовал разные значения для maxgap, но, похоже, ни одно из них не решило мою проблему. Я предполагал, что с помощью функции group_by это будет работать правильно, но это не так. Кто-нибудь знает какие-либо решения?
РЕДАКТИРОВАТЬ: Единственный способ сделать то, что мне нужно, - разделить набор данных на отдельный набор данных для каждой уникальной страны, используя следующий код:
mylist <- split(data, data$country)
alb <- mylist[1]
alb <- as_data_frame(alb)
alg <- mylist[2]
alg <- as_data_frame(alg)
ang <- mylist[3]
ang <- as_data_frame(ang)
и затем используйте функцию na.approx для отдельных наборов данных по одному.
РЕДАКТИРОВАТЬ 2:
Я попробовал решение, предложенное Маркусом ниже, и оно, похоже, не работает. Это результат использования предложенного кода для значений для Анголы:
Country Year Broadband Broadband_imp
Algeria 2014 1599692 1599692
Algeria 2015 2269348 2269348
Algeria 2016 2858906 2858906
Angola 2000 NA 2451556.286
Angola 2001 NA 2044206.571
Angola 2002 NA 1636856.857
Angola 2003 NA 1229507.143
Angola 2004 NA 822157.429
Angola 2005 NA 414807.714
Angola 2006 7458 7458
Angola 2007 11700 11700
Как вы можете видеть, вмененные значения для Анголы 2000-2005 гг., По-видимому, были рассчитаны с использованием значений из Алжира, поскольку вмененные значения намного выше, чем они должны быть даны для значения Анголы 2006 года в 7458.
РЕДАКТИРОВАТЬ 3: Это полный код, который я использовал -
data <- read_excel("~/Documents/data.xlsx")
> dput(head(data))
structure(list(continent = c("Europe", "Europe", "Europe", "Europe",
"Europe", "Europe"), country = c("Albania", "Albania", "Albania",
"Albania", "Albania", "Albania"), Year = c(2000, 2001, 2002,
2003, 2004, 2005), `Individuals Using Internet, %, WB` = c(0.114097347,
0.325798377, 0.390081273, 0.971900415, 2.420387798, 6.043890864
), `Secure Internet Servers, WB` = c(NA, 1, NA, 1, 2, 1), `Mobile Cellular
Subscriptions, WB` = c(29791,
392650, 851000, 1100000, 1259590, 1530244), `Fixed Broadband Subscriptions,
WB` = c(NA,
NA, NA, NA, NA, 272), `Trade, % GDP, WB` = c(55.9204287230026,
57.4303612453301, 63.9342407411882, 65.4406219482911, 66.3578254370479,
70.2953012017195), `Air transport, freight (million ton-km)` = c(0.003,
0.003, 0.144, 0.088, 0.099, 0.1), `Air Transport, registered carrier
departures worldwide, WB` = c(3885,
3974, 3762, 3800, 4104, 4309), `FDI, net, inflows, % GDP, WB` =
c(3.93717707227928,
5.10495722596557, 3.04391445388559, 3.09793068135411, 4.66563777108359,
3.21722676118428), `Number of Airports, WFB` = c(10, 11, 11,
11, 11, 11), `Currently under EU Arms Sanctions` = c(0, 0, 0,
0, 0, 0), `Currently under EU Economic Sanctions` = c(0, 0, 0,
0, 0, 0), `Currently under UN Arms Sanctions` = c(0, 0, 0, 0,
0, 0), `Currently under UN Economic Sanctions` = c(0, 0, 0, 0,
0, 0), `Currently under US Arms Embargo` = c(0, 0, 0, 0, 0, 0
), `Currently under US Economic Sanctions` = c(0, 0, 0, 0, 0,
0)), .Names = c("continent", "country", "Year", "Individuals Using Internet,
%, WB",
"Secure Internet Servers, WB", "Mobile Cellular Subscriptions, WB",
"Fixed Broadband Subscriptions, WB", "Trade, % GDP, WB", "Air transport,
freight (million ton-km)",
"Air Transport, registered carrier departures worldwide, WB",
"FDI, net, inflows, % GDP, WB", "Number of Airports, WFB", "Currently under EU
Arms Sanctions",
"Currently under EU Economic Sanctions", "Currently under UN Arms Sanctions",
"Currently under UN Economic Sanctions", "Currently under US Arms Embargo",
"Currently under US Economic Sanctions"), row.names = c(NA, -6L
), class = c("tbl_df", "tbl", "data.frame"))
data_imputed <- data %>%
group_by(country) %>%
mutate(broadband_imp = na.approx(broadband, maxgap=Inf, rule = 2))
1 ответ
Ты можешь использовать group_by
а также mutate
:
library(tidyverse)
library(zoo)
df_imputed <- df %>%
group_by(Country) %>%
mutate(Broadband_imputed = na.approx(Broadband, maxgap = Inf, rule = 2))
Который дает
> head(df_imputed)
# A tibble: 6 x 4
# Groups: Country [1]
Country Year Broadband Broadband_imputed
<fctr> <int> <int> <dbl>
1 Albania 2000 NA 272
2 Albania 2001 NA 272
3 Albania 2002 NA 272
4 Albania 2003 NA 272
5 Albania 2004 NA 272
6 Albania 2005 272 272
а также
> df_imputed %>% filter(Country == 'Algeria')
# A tibble: 5 x 4
# Groups: Country [1]
Country Year Broadband Broadband_imputed
<fctr> <int> <int> <dbl>
1 Algeria 2000 NA 18000
2 Algeria 2001 NA 18000
3 Algeria 2002 NA 18000
4 Algeria 2003 18000 18000
5 Algeria 2004 36000 36000
ДАННЫЕ
df <- read.table(text = "Country Year Broadband
Albania 2000 NA
Albania 2001 NA
Albania 2002 NA
Albania 2003 NA
Albania 2004 NA
Albania 2005 272
Albania 2006 NA
Albania 2007 10000
Albania 2008 64000
Albania 2009 92000
Albania 2010 105539
Albania 2011 128210
Albania 2012 160088
Albania 2013 182556
Albania 2014 207931
Albania 2015 242870
Albania 2016 263874
Albania 2017 NA
Algeria 2000 NA
Algeria 2001 NA
Algeria 2002 NA
Algeria 2003 18000
Algeria 2004 36000", header = TRUE)