5.3 列の分割と結合

table3rateの列に複数の変数(populationcases)の情報が文字列として格納されており、tidyではありません。このようにひとつの列に含まれている文字列を、複数の列に分割したい場合は、separate()関数を用います。separate()関数は、dplyrのverbと同様に、第1引数はデータフレームで、出力もデータフレームです。第1引数以外で必要な引数としては,分割元の変数を指定するcolと分割した後に設定する変数名のベクトルintoとなります。table3の場合、colrateintoc("cases", "population")を指定します。

table3
## # A tibble: 6 x 3
##   country      year rate             
##   <chr>       <int> <chr>            
## 1 Afghanistan  1999 745/19987071     
## 2 Afghanistan  2000 2666/20595360    
## 3 Brazil       1999 37737/172006362  
## 4 Brazil       2000 80488/174504898  
## 5 China        1999 212258/1272915272
## 6 China        2000 213766/1280428583
table3 %>% 
  separate(rate, c("cases", "population"))
## # A tibble: 6 x 4
##   country      year cases  population
##   <chr>       <int> <chr>  <chr>     
## 1 Afghanistan  1999 745    19987071  
## 2 Afghanistan  2000 2666   20595360  
## 3 Brazil       1999 37737  172006362 
## 4 Brazil       2000 80488  174504898 
## 5 China        1999 212258 1272915272
## 6 China        2000 213766 1280428583

これでもOKですが、分割された後の変数が文字列になっているので、数字のみの文字列であれば、convert引数をTRUEに設定すると、数値に変換してくれます。

table3 %>% 
  separate(rate, c("cases", "population"), convert = TRUE)
## # A tibble: 6 x 4
##   country      year  cases population
##   <chr>       <int>  <int>      <int>
## 1 Afghanistan  1999    745   19987071
## 2 Afghanistan  2000   2666   20595360
## 3 Brazil       1999  37737  172006362
## 4 Brazil       2000  80488  174504898
## 5 China        1999 212258 1272915272
## 6 China        2000 213766 1280428583

また、区切り文字については、デフォルトでは数値以外の文字となっていますが、指定したい場合は、sep引数を指定します。(table3の場合は指定しなくてもOKです。)

table3 %>% 
  separate(rate, c("cases", "population"), sep = "/")

separate()関数とは反対に、複数の変数をひとつの列に結合したい場合は、unite()関数を用います。ここでは、unite()関数の動作確認のために、table3yearを先頭2桁のcenturyと後ろ2桁のyearに分割をしてから、再度結合することを考えます。sep引数に数値を与えると、その数値の桁数分で分割されます。

table5 <- table3 %>% 
  separate(year, c("century", "year", sep = 2))
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 6 rows [1, 2, 3,
## 4, 5, 6].
table5
## # A tibble: 6 x 5
##   country     century year  `2`   rate             
##   <chr>       <chr>   <chr> <chr> <chr>            
## 1 Afghanistan 1999    <NA>  <NA>  745/19987071     
## 2 Afghanistan 2000    <NA>  <NA>  2666/20595360    
## 3 Brazil      1999    <NA>  <NA>  37737/172006362  
## 4 Brazil      2000    <NA>  <NA>  80488/174504898  
## 5 China       1999    <NA>  <NA>  212258/1272915272
## 6 China       2000    <NA>  <NA>  213766/1280428583

centuryyearの列をunite()関数で結合して、改めてyear列とします。unite()関数もdplyrのverbと同様に、第1引数はデータフレームで、出力もデータフレームです。第1引数以外で必要な引数としては,結合後の変数名colと、select()と同様に指定された結合対象の変数名となります。

table5 %>% 
  unite(col = new, century, year)
## # A tibble: 6 x 4
##   country     new     `2`   rate             
##   <chr>       <chr>   <chr> <chr>            
## 1 Afghanistan 1999_NA <NA>  745/19987071     
## 2 Afghanistan 2000_NA <NA>  2666/20595360    
## 3 Brazil      1999_NA <NA>  37737/172006362  
## 4 Brazil      2000_NA <NA>  80488/174504898  
## 5 China       1999_NA <NA>  212258/1272915272
## 6 China       2000_NA <NA>  213766/1280428583

このように、デフォルトではアンダースコア_によって結合されますが、結合文字を指定したい場合はsep変数を指定します(以下の例は空の文字列)。

table5 %>% 
  unite(col = new, century, year, sep = "")
## # A tibble: 6 x 4
##   country     new    `2`   rate             
##   <chr>       <chr>  <chr> <chr>            
## 1 Afghanistan 1999NA <NA>  745/19987071     
## 2 Afghanistan 2000NA <NA>  2666/20595360    
## 3 Brazil      1999NA <NA>  37737/172006362  
## 4 Brazil      2000NA <NA>  80488/174504898  
## 5 China       1999NA <NA>  212258/1272915272
## 6 China       2000NA <NA>  213766/1280428583