160  人口動態統計データの加工2

library(tidyverse)

dat <- read_csv(
  file = "data/mc360000.csv", 
  locale=locale(encoding="shift-jis"),
  skip = 3, 
  col_names = FALSE
)

ここでは、列名を作成することを考えます。

View(dat)

データを眺めると、

1行目 総数 NA … NA NA … 2行目 死亡数 NA … 百分率 NA … 3行目 1995  2000 … 1995 2000 …

と、こんな感じで、1行目から3行目までで合わせて列のような形です。

これを

1行目 総数 総数 … 2行目 死亡数 死亡数 … 3行目 1995  2000  …

として、

総数_死亡数_1995 | 総数_死亡数_2000 | …

というような形の列名にすることができれば、pivot_longerで処理をまとめてできそうです。

ここで1行ずつ抜き出してベクトルに変換しましょう。

1行を抜き出すには、slice関数を利用するか、

data[1,]

の書き方を利用します

row1 <- dat %>% slice(1)
row1
# A tibble: 1 × 61
  X1    X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 <NA>  総数  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
# ℹ 48 more variables: X14 <chr>, X15 <chr>, X16 <chr>, X17 <chr>, X18 <chr>,
#   X19 <chr>, X20 <chr>, X21 <chr>, X22 <chr>, X23 <chr>, X24 <chr>,
#   X25 <chr>, X26 <chr>, X27 <chr>, X28 <chr>, X29 <chr>, X30 <chr>,
#   X31 <chr>, X32 <chr>, X33 <chr>, X34 <chr>, X35 <chr>, X36 <chr>,
#   X37 <chr>, X38 <chr>, X39 <chr>, X40 <chr>, X41 <chr>, X42 <chr>,
#   X43 <chr>, X44 <chr>, X45 <chr>, X46 <chr>, X47 <chr>, X48 <chr>,
#   X49 <chr>, X50 <chr>, X51 <chr>, X52 <chr>, X53 <chr>, X54 <chr>, …
row1 <- dat[1,]
row1
# A tibble: 1 × 61
  X1    X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 <NA>  総数  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
# ℹ 48 more variables: X14 <chr>, X15 <chr>, X16 <chr>, X17 <chr>, X18 <chr>,
#   X19 <chr>, X20 <chr>, X21 <chr>, X22 <chr>, X23 <chr>, X24 <chr>,
#   X25 <chr>, X26 <chr>, X27 <chr>, X28 <chr>, X29 <chr>, X30 <chr>,
#   X31 <chr>, X32 <chr>, X33 <chr>, X34 <chr>, X35 <chr>, X36 <chr>,
#   X37 <chr>, X38 <chr>, X39 <chr>, X40 <chr>, X41 <chr>, X42 <chr>,
#   X43 <chr>, X44 <chr>, X45 <chr>, X46 <chr>, X47 <chr>, X48 <chr>,
#   X49 <chr>, X50 <chr>, X51 <chr>, X52 <chr>, X53 <chr>, X54 <chr>, …

それで、これをベクトルに変換したいのですがそれは、as_vector()でできます

as_vector(row1)
    X1     X2     X3     X4     X5     X6     X7     X8     X9    X10    X11 
    NA "総数"     NA     NA     NA     NA     NA     NA     NA     NA     NA 
   X12    X13    X14    X15    X16    X17    X18    X19    X20    X21    X22 
    NA     NA     NA     NA     NA     NA     NA     NA     NA     NA   "男" 
   X23    X24    X25    X26    X27    X28    X29    X30    X31    X32    X33 
    NA     NA     NA     NA     NA     NA     NA     NA     NA     NA     NA 
   X34    X35    X36    X37    X38    X39    X40    X41    X42    X43    X44 
    NA     NA     NA     NA     NA     NA     NA     NA   "女"     NA     NA 
   X45    X46    X47    X48    X49    X50    X51    X52    X53    X54    X55 
    NA     NA     NA     NA     NA     NA     NA     NA     NA     NA     NA 
   X56    X57    X58    X59    X60    X61 
    NA     NA     NA     NA     NA     NA 

ということで、

row1 <- dat %>% slice(1) %>% as_vector()
row2 <- dat %>% slice(2) %>% as_vector()
row3 <- dat %>% slice(3) %>% as_vector()

dat_colname <- tibble(
  r1 = row1,
  r2 = row2,
  r3 = row3
)

dat_colname
# A tibble: 61 × 3
   r1    r2     r3   
   <chr> <chr>  <chr>
 1 <NA>  <NA>   <NA> 
 2 総数  死亡数 1995 
 3 <NA>  <NA>   2000 
 4 <NA>  <NA>   2005 
 5 <NA>  <NA>   2010 
 6 <NA>  <NA>   2014 
 7 <NA>  <NA>   2015 
 8 <NA>  <NA>   2016 
 9 <NA>  <NA>   2017 
10 <NA>  <NA>   2018 
# ℹ 51 more rows

このデータから列名をつくります。

まず、欠損値をうめます。

dat_colname <- dat_colname %>% 
  fill(r1,r2,r3,.direction="down")

dat_colname
# A tibble: 61 × 3
   r1    r2     r3   
   <chr> <chr>  <chr>
 1 <NA>  <NA>   <NA> 
 2 総数  死亡数 1995 
 3 総数  死亡数 2000 
 4 総数  死亡数 2005 
 5 総数  死亡数 2010 
 6 総数  死亡数 2014 
 7 総数  死亡数 2015 
 8 総数  死亡数 2016 
 9 総数  死亡数 2017 
10 総数  死亡数 2018 
# ℹ 51 more rows

そして、separate関数の反対の動作をする関数があるのでそれを利用していましょう。uniteです。

dat_colname2 <- dat_colname %>% 
  unite(col = "coln", r1, r2, r3,sep="_", remove=FALSE)

View(dat_colname2)

この作成したcoln列をベクトルとしてとりだして、datの列名にしてあげればよいです

ベクトルとして列を取り出す場合は、pull()を使います。また、setNames関数で文字ベクトルを一括して表の列名にしていできます。

vec_coln <- dat_colname2 %>% 
  pull(coln)

vec_coln
 [1] "NA_NA_NA"         "総数_死亡数_1995" "総数_死亡数_2000" "総数_死亡数_2005"
 [5] "総数_死亡数_2010" "総数_死亡数_2014" "総数_死亡数_2015" "総数_死亡数_2016"
 [9] "総数_死亡数_2017" "総数_死亡数_2018" "総数_死亡数_2019" "総数_百分率_1995"
[13] "総数_百分率_2000" "総数_百分率_2005" "総数_百分率_2010" "総数_百分率_2014"
[17] "総数_百分率_2015" "総数_百分率_2016" "総数_百分率_2017" "総数_百分率_2018"
[21] "総数_百分率_2019" "男_死亡数_1995"   "男_死亡数_2000"   "男_死亡数_2005"  
[25] "男_死亡数_2010"   "男_死亡数_2014"   "男_死亡数_2015"   "男_死亡数_2016"  
[29] "男_死亡数_2017"   "男_死亡数_2018"   "男_死亡数_2019"   "男_百分率_1995"  
[33] "男_百分率_2000"   "男_百分率_2005"   "男_百分率_2010"   "男_百分率_2014"  
[37] "男_百分率_2015"   "男_百分率_2016"   "男_百分率_2017"   "男_百分率_2018"  
[41] "男_百分率_2019"   "女_死亡数_1995"   "女_死亡数_2000"   "女_死亡数_2005"  
[45] "女_死亡数_2010"   "女_死亡数_2014"   "女_死亡数_2015"   "女_死亡数_2016"  
[49] "女_死亡数_2017"   "女_死亡数_2018"   "女_死亡数_2019"   "女_百分率_1995"  
[53] "女_百分率_2000"   "女_百分率_2005"   "女_百分率_2010"   "女_百分率_2014"  
[57] "女_百分率_2015"   "女_百分率_2016"   "女_百分率_2017"   "女_百分率_2018"  
[61] "女_百分率_2019"  
dat
# A tibble: 29 × 61
   X1    X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
   <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
 1 <NA>  総数  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
 2 <NA>  死亡… <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  百分… <NA> 
 3 <NA>  1995  2000  2005  2010  2014  2015  2016  2017  2018  2019  1995  2000 
 4 X60-… 21420 30251 30553 29554 24417 23152 21021 20468 20031 19425 100   100  
 5 X60…  8     10    7     8     7     6     5     4     4     10    0     0    
 6 X61…  235   359   375   307   240   200   191   148   170   162   1.1   1.2  
 7 X62…  -     1     3     -     2     1     2     2     1     -     -     0    
 8 X63…  1     1     3     -     2     3     -     -     -     -     0     0    
 9 X64…  111   164   197   187   158   176   165   162   161   151   0.5   0.5  
10 X65…  1     4     5     4     10    3     6     3     4     3     0     0    
# ℹ 19 more rows
# ℹ 48 more variables: X14 <chr>, X15 <chr>, X16 <chr>, X17 <chr>, X18 <chr>,
#   X19 <chr>, X20 <chr>, X21 <chr>, X22 <chr>, X23 <chr>, X24 <chr>,
#   X25 <chr>, X26 <chr>, X27 <chr>, X28 <chr>, X29 <chr>, X30 <chr>,
#   X31 <chr>, X32 <chr>, X33 <chr>, X34 <chr>, X35 <chr>, X36 <chr>,
#   X37 <chr>, X38 <chr>, X39 <chr>, X40 <chr>, X41 <chr>, X42 <chr>,
#   X43 <chr>, X44 <chr>, X45 <chr>, X46 <chr>, X47 <chr>, X48 <chr>, …

ちょうど、

length(vec_coln)
[1] 61
ncol(dat)
[1] 61

ベクトルの長さと列数が一致していますね?

dat2 <- dat %>% setNames(vec_coln)

View(dat2)

うまくいきました。これで、最初の3行は必要ないので、消しましょう。あと、4行目、X60-X84 総数 に該当する行の消しておきます(個別のデータのみにしたい状況としておきまs)slice関数は、中の数字に―をつけると削除するという意味になるので、

dat3 <- dat2 %>% 
  slice(-(1:4))

View(dat3)

いかがでしょうか?

NA_NA_NAという列名はきになるので適当に変えておきましょう

dat4 <- dat3 %>% 
  rename(cause = NA_NA_NA)

View(dat4)