首页 > 解决方案 > 在 R 中将面板数据转换为 Long

问题描述

我目前的数据是 1920 年至 2018 年间的导弹。目标是衡量一个国家在 1920 年至 2018 年期间每年部署不同类型导弹的能力。出现的问题是每个国家的数据有多个观测值,而且通常是每年. 这会产生问题,因为例如,如果一个国家在 1970 年采用了一种空对空导弹并进口,然后在 1980 年开发了一种空对空和空对地导弹并在国内生产,则需要反映这种变化。目标是每个国家每年都有一个独特的行/观察。还应该注意的是,假设该国是否可以在 1970 年生产 Air to air,他们可以在 2018 年之前生产。当前:

YearAcquired CountryCode CountryName Domestic AirtoAir
     2014         670    Saudi Arabia    0        1
     2017         670    Saudi Arabia    1        1
     2016          2    United States    1        1

期望:

YearAcquired CountryCode CountryName Domestic AirtoAir
     2014         670    Saudi Arabia    0        1
     2015         670    Saudi Arabia    0        1
     2016         670    Saudi Arabia    0        1
     2017         670    Saudi Arabia    1        1
     2018         670    Saudi Arabia    1        1
     2016          2    United States    0        1
     2017          2    United States    0        1
     2018          2    United States    0        1

注意:有很多条目,所以我希望它为每个国家/地区从 1920 年到 2018 年生成,即使它们将有直零。这不是必需的,但它会很棒!

标签: rformatlong-integer

解决方案


使用 ( )...

如果您只需要填写每个国家/地区的内部年份...

df <- read.table(header = TRUE, as.is = TRUE, text = "
YearAcquired  countrycode   CountryName    Domestic  AirtoAir
2014          670           'Saudi Arabia'    0         1
2017          670           'Saudi Arabia'    1         1
2016          2             'United States'   1         1
")

library(dplyr)
library(tidyr)

df %>% 
  group_by(countrycode) %>% 
  complete(YearAcquired = full_seq(YearAcquired, 1), countrycode, CountryName) %>% 
  arrange(countrycode, YearAcquired) %>% 
  fill(Domestic, AirtoAir)

#> # A tibble: 5 x 5
#> # Groups:   countrycode [2]
#>   YearAcquired countrycode CountryName   Domestic AirtoAir
#>          <dbl>       <int> <chr>            <int>    <int>
#> 1         2016           2 United States        1        1
#> 2         2014         670 Saudi Arabia         0        1
#> 3         2015         670 Saudi Arabia         0        1
#> 4         2016         670 Saudi Arabia         0        1
#> 5         2017         670 Saudi Arabia         1        1

如果您想将每个国家/地区扩展到数据集中的所有年份...

df <- read.table(header = TRUE, as.is = TRUE, text = "
YearAcquired  countrycode   CountryName    Domestic  AirtoAir
2014          670           'Saudi Arabia'    0         1
2017          670           'Saudi Arabia'    1         1
2016          2             'United States'   1         1
")

library(dplyr)
library(tidyr)

df %>% 
  complete(YearAcquired = full_seq(YearAcquired, 1), 
           nesting(countrycode, CountryName)) %>% 
  group_by(countrycode) %>% 
  arrange(countrycode, YearAcquired) %>% 
  fill(Domestic, AirtoAir) %>% 
  mutate_at(vars(Domestic, AirtoAir), funs(if_else(is.na(.), 0L, .)))

#> # A tibble: 8 x 5
#> # Groups:   countrycode [2]
#>   YearAcquired countrycode CountryName   Domestic AirtoAir
#>          <dbl>       <int> <chr>            <int>    <int>
#> 1         2014           2 United States        0        0
#> 2         2015           2 United States        0        0
#> 3         2016           2 United States        1        1
#> 4         2017           2 United States        1        1
#> 5         2014         670 Saudi Arabia         0        1
#> 6         2015         670 Saudi Arabia         0        1
#> 7         2016         670 Saudi Arabia         0        1
#> 8         2017         670 Saudi Arabia         1        1

推荐阅读