繁体   English   中英

R 中的逐行线性回归和预测

[英]Row-wise linear regression and prediction in R

我有两个国家数据集,第一个从 2012 年到 2020 年,看起来像这样:

> head(y)
              Country 2012 2013 2014 2015  2016  2017  2018  2019  2020
1         Afghanistan    0  0.0    0    0  0.00  4.00  7.00 22.00 26.00
2             Albania    0  0.0    0   35 80.20 85.30 85.50 95.00 98.38
3             Algeria    0  0.0    0    0  3.62 30.49 52.84 53.63 76.18
4             Andorra   50 50.0   50   50 50.00 85.00 85.00 85.00 85.00
5              Angola    7  7.0    7    7  8.00  8.00  8.00 18.00 30.00
6 Antigua and Barbuda   65 78.6   80   98 99.00 99.00 99.00 99.00 99.00

第二个是从 2012 年到 2030 年,看起来像这样:

> head(x)
  CountryName CountryCode CountryCodeID ProductID     Y2012 Y2013 Y2014    Y2015     Y2016     Y2017     Y2018     Y2019     Y2020     Y2021     Y2022     Y2023     Y2024     Y2025     Y2026     Y2027     Y2028     Y2029     Y2030
1     Antigua          AA           157    178271 98.000000 98.00 98.00 98.35281  99.22350  99.30797  99.38018  99.44286  99.49796  99.54694  99.59088  99.63063 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000
2     Albania          AB           158    178271 99.000000 99.00 99.00 99.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000
3      Angola          AG           161    178271 47.000000 53.00 46.00 60.00000  70.12252  78.48148  84.95833  89.19728  92.40534  95.10876  96.64146  97.54840  98.10920  98.46371  99.36144  99.42651  99.48353  99.53406  99.57929
4  Azerbaijan          AJ           163    178271 96.500000 96.90 97.10 97.30000  98.23938  98.78344  99.10162 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000
5     Algeria          AL           164    178271  1.142043  6.00 23.23 46.00000  56.33254  66.41615  75.59252  82.67079  88.15954  91.56166  94.41373  96.92251  98.01697  98.65143  99.02451 100.00000 100.00000 100.00000 100.00000
6     Armenia          AM           165    178271 96.300000 97.68 98.80 99.90000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000 100.00000

我想对每个国家/地区的 2012 年至 2020 年之间的日期进行类似lm(y ~ x)的线性回归,然后根据同一时期的x预测 2021 年至 2030 年的y

谁能帮我实现这一目标? 由于我有 139 个国家(行),因此从两个数据集中提取每个国家并将它们组合在一个数据框中然后运行回归和预测是很挑剔的,更有效的方法将大有帮助。

首先,最好将你的数据转换成整齐的格式,这样每年的观察就有一行。 我将在模拟数据上进行演示:

library(dplyr)
library(tidyr)

N_COUNTRIES <- 3
YEARS <- 2012:2020
N_YEARS <- length(YEARS)

# simulate x data
countries <- LETTERS[1:N_COUNTRIES]
mat_x <- matrix(runif(N_COUNTRIES*N_YEARS, 0, 100), nrow = N_COUNTRIES)
colnames(mat_x) <- YEARS
df_x <- bind_cols(country = countries, mat_x)

# simulate y data
mat_y <- matrix(runif(N_COUNTRIES*N_YEARS, 0, 50), nrow = N_COUNTRIES)
colnames(mat_y) <- paste0("Y", YEARS)
df_y <- bind_cols(
  country = countries,
  some_other_column = sample(1:100, N_COUNTRIES), mat_y
)

# convert df_x to long format
df_x_long <- 
  df_x %>% 
  pivot_longer(-country, names_to = "year", values_to = "x") %>% 
  mutate(across(year, as.numeric))

head(df_x_long)
#> # A tibble: 6 × 3
#>   country  year     x
#>   <chr>   <dbl> <dbl>
#> 1 A        2012  67.6
#> 2 A        2013  71.9
#> 3 A        2014  48.7
#> 4 A        2015  20.0
#> 5 A        2016  13.3
#> 6 A        2017  62.4

# convert df_y to long format
df_y_long <- 
  df_y %>% 
  select(country, starts_with("Y")) %>% 
  pivot_longer(-country, names_to = "year", values_to = "y") %>% 
  mutate(year = as.numeric(gsub("^Y", "", year)))

现在很容易将 x 和 y 观测值合并在一起。

# join
df_xy_long <- inner_join(df_x_long, df_y_long, by = c("country", "year"))

head(df_xy_long)
#> # A tibble: 6 × 4
#>   country  year     x     y
#>   <chr>   <dbl> <dbl> <dbl>
#> 1 A        2012  67.6  13.6
#> 2 A        2013  71.9  19.5
#> 3 A        2014  48.7  35.0
#> 4 A        2015  20.0  31.9
#> 5 A        2016  13.3  16.7
#> 6 A        2017  62.4  47.4

有了这个,我们可以使用tidyr::nest()将每个国家的观察结果放入单独的盒子中,然后在每个盒子上运行lm

# nest and model
df_xy_nested <- 
  df_xy_long %>% 
  group_by(country) %>% 
  nest() %>% 
  rowwise() %>% 
  mutate(model = list(lm(y ~ x, data = data))) %>% 
  ungroup()

head(df_xy_nested)
#> # A tibble: 3 × 3
#>   country data             model 
#>   <chr>   <list>           <list>
#> 1 A       <tibble [9 × 3]> <lm>  
#> 2 B       <tibble [9 × 3]> <lm>  
#> 3 C       <tibble [9 × 3]> <lm>

data列中的每个元素都是 dataframe 本身, model列中的每个元素都是lm model。

df_xy_nested$data[[1]]
#> # A tibble: 9 × 3
#>    year     x     y
#>   <dbl> <dbl> <dbl>
#> 1  2012  67.6 13.6 
#> 2  2013  71.9 19.5 
#> 3  2014  48.7 35.0 
#> 4  2015  20.0 31.9 
#> 5  2016  13.3 16.7 
#> 6  2017  62.4 47.4 
#> 7  2018  38.1 40.9 
#> 8  2019  96.1 36.6 
#> 9  2020  24.8  2.57

df_xy_nested$model[[1]]
#> 
#> Call:
#> lm(formula = y ~ x, data = data)
#> 
#> Coefficients:
#> (Intercept)            x  
#>     19.3173       0.1587

您可能想像这样提取 model 系数:

df_xy_nested %>% 
  rowwise() %>% 
  mutate(
    coef_intercept = model$coefficients[[1]],
    coef_x = model$coefficients[[2]]
  )
#> # A tibble: 3 × 5
#> # Rowwise: 
#>   country data             model  coef_intercept  coef_x
#>   <chr>   <list>           <list>          <dbl>   <dbl>
#> 1 A       <tibble [9 × 3]> <lm>             19.3  0.159 
#> 2 B       <tibble [9 × 3]> <lm>             29.9 -0.161 
#> 3 C       <tibble [9 × 3]> <lm>             18.3  0.0427

代表 package (v2.0.1) 于 2022 年 8 月 3 日创建

有关嵌套数据建模的更多详细信息,我建议您阅读:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM