10/ データ・ハンドリング(2)
関西大学総合情報学部
すぐに実習できるように準備しておきましょう。
例) 大陸ごとに政治的権利(FH_PR)と市民的自由(FH_CL)の平均値を計算する
# A tibble: 5 × 3
Continent PR CL
<chr> <dbl> <dbl>
1 Africa 15.8 25.8
2 America 29.4 42.6
3 Asia 14.7 24.2
4 Europe 31.9 47.6
5 Oceania 31.8 47.2
変数が持つ情報を要約した数値
元の情報:
summarise()の使い方summarise(): 記述統計量を計算する{dplyr}の関数
記述統計の関数の例
mean():平均値median():中央値sd():不偏分散の平方根(一般的に「標準偏差」と呼ばれるもの)var():不偏分散IQR():四分位範囲min()、max():最小値と最大値n():ケース数(引数不要)例) dfのPopulationとAreaの平均値(mean())を計算
summarise()内に異なる関数を使うことも可能
例) dfのPopulationとAreaの平均値(mean())と標準偏差(sd())を計算
summarise()内に出力される結果の列名 = 関数()を指定
例) dfのPopulationとAreaの平均値(mean())と標準偏差(sd())を計算し、結果の列名をMean_Pop、SD_Popなどとする
{dplyr}のgroup_by()を使用
例) dfのContinentでデータをグループ化し、PPP_per_capitaの平均値を計算
例) dfのContinentとG20でデータをグループ化し、HDI_2018の平均値を計算
`summarise()` has grouped output by 'Continent'. You can override using the
`.groups` argument.
# A tibble: 10 × 3
# Groups: Continent [5]
Continent G20 Mean_HDI
<chr> <dbl> <dbl>
1 Africa 0 0.550
2 Africa 1 0.705
3 America 0 0.727
4 America 1 0.84
5 Asia 0 0.710
6 Asia 1 0.798
7 Europe 0 0.859
8 Europe 1 0.877
9 Oceania 0 0.729
10 Oceania 1 0.938
summarise()謎のメッセージが出力される
## `summarise()` has grouped output by 'Continent'. You can override using
the `.groups` argument.
とりあえず、group_by()の後にsummarise()を使う場合、summarise()の最後に.groups = "drop"を追加する。
quantile()など)を使う場合、問題が生じる可能性あり
summarise()の後に更にパイプ(|>)を使って計算を続ける場合.groups = "drop"をしておけば安全summarise()の代わりにreframe()を使えば.groups = "drop"は不要({dplyr} 1.1.0から).groups = "drop"を追加する謎のメッセージが出力されなくなる
# A tibble: 10 × 3
Continent G20 Mean_HDI
<chr> <dbl> <dbl>
1 Africa 0 0.550
2 Africa 1 0.705
3 America 0 0.727
4 America 1 0.84
5 Asia 0 0.710
6 Asia 1 0.798
7 Europe 0 0.859
8 Europe 1 0.877
9 Oceania 0 0.729
10 Oceania 1 0.938
summarise()の中にn()を使用
# A tibble: 5 × 4
Continent Mean_PPP SD_PPP Cases
<chr> <dbl> <dbl> <int>
1 Africa 5667. 6015. 54
2 America 18100. 12601. 36
3 Asia 22728. 24067. 42
4 Europe 37783. 21276. 50
5 Oceania 27573. 21984. 4
across()関数を利用: 詳細は教科書第14.1章を参照
例) dfのPopulationからPPP列まで平均値と標準偏差を計算し、結果の変数名は元の変数名_Mean、元の変数名_SDとする
# A tibble: 1 × 8
Population_Mean Population_SD Area_Mean Area_SD GDP_Mean GDP_SD PPP_Mean
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 41737773. 41737773. 696069. 696069. 473031. 473031. 717953.
# ℹ 1 more variable: PPP_SD <dbl>
mutate(): データフレームの変数を用いた計算を行い、新しい列として追加
例) dfのPopulationをAreaで割り(=人口密度)、Densityという名の列として追加する
例) dfのPopulationをAreaで割り(人口密度)、Densityという名の列として追加する
# A tibble: 186 × 19
Country Population Area GDP PPP GDP_per_capita PPP_per_capita G7
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Afghanis… 38928346 6.53e5 1.91e4 82737. 491. 2125. 0
2 Albania 2877797 2.74e4 1.53e4 39658. 5309. 13781. 0
3 Algeria 43851044 2.38e6 1.70e5 496572. 3876. 11324. 0
4 Andorra 77265 4.7 e2 3.15e3 NA 40821. NA 0
5 Angola 32866272 1.25e6 9.46e4 218533. 2879. 6649. 0
# ℹ 181 more rows
# ℹ 11 more variables: G20 <dbl>, OECD <dbl>, HDI_2018 <dbl>,
# Polity_Score <dbl>, Polity_Type <chr>, FH_PR <dbl>, FH_CL <dbl>,
# FH_Total <dbl>, FH_Status <chr>, Continent <chr>, Density <dbl>
mutate()内に.after、または.beforeを指定
relocate()関数と同じ仕組み(第9回)例) PopulationをAreaで割り、Densityという名の新しい列Areaの後に追加する。
# A tibble: 186 × 19
Country Population Area Density GDP PPP GDP_per_capita
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Afghanistan 38928346 652860 59.6 1.91e4 8.27e4 491.
2 Albania 2877797 27400 105. 1.53e4 3.97e4 5309.
3 Algeria 43851044 2381740 18.4 1.70e5 4.97e5 3876.
4 Andorra 77265 470 164. 3.15e3 NA 40821.
5 Angola 32866272 1246700 26.4 9.46e4 2.19e5 2879.
6 Antigua and Barbuda 97929 440 223. 1.73e3 2.08e3 17643.
7 Argentina 45195774 2736690 16.5 4.50e5 1.04e6 9949.
8 Armenia 2963243 28470 104. 1.37e4 3.84e4 4614.
9 Australia 25499884 7682300 3.32 1.39e6 1.28e6 54615.
10 Austria 9006398 82409 109. 4.46e5 5.03e5 49555.
# ℹ 176 more rows
# ℹ 12 more variables: PPP_per_capita <dbl>, G7 <dbl>, G20 <dbl>, OECD <dbl>,
# HDI_2018 <dbl>, Polity_Score <dbl>, Polity_Type <chr>, FH_PR <dbl>,
# FH_CL <dbl>, FH_Total <dbl>, FH_Status <chr>, Continent <chr>
各国が世界人口に占める割合を計算し、降順で出力
dfのPopulationの合計をTotal_Popという列として追加する。PopulationをTotal_Popで割り、100を掛ける。結果はShare_Popという名の列としてPopulation後に追加する。CountryからShare_Popまでの列のみ残す。Total_Pop列を除外する。Share_Popが大きい順で行を並び替える# A tibble: 186 × 3
Country Population Share_Pop
<chr> <dbl> <dbl>
1 China 1447470092 18.6
2 India 1380004385 17.8
3 United States 334308644 4.31
4 Indonesia 273523615 3.52
5 Pakistan 220892340 2.85
6 Brazil 212559417 2.74
7 Nigeria 206139589 2.66
8 Bangladesh 164689383 2.12
9 Russia 145934462 1.88
10 Mexico 128932753 1.66
# ℹ 176 more rows
G7、G20、OECDのいずれかに加盟している国を「先進国」、それ以外は「その他」とし、二つのグループの人口密度、人間開発指数、民主主義度の平均値を出力する。
dfを利用するDevelopedという列を追加し、G7、G20、OECDのいずれかに加盟した国なら"先進国"、それ以外なら"その他"とする。Densityという名の列として追加する。HDI_2018とPolity_Scoreのいずれかが欠損した行を除外する。Developed変数でデータをグルーピングする。HDI_2018、Polity_Score、Densityの平均値を求める。df2という名前のオブジェクトとして作業環境内に格納する。df2 <- df |>
mutate(Developed = G7 + G20 + OECD,
Developed = if_else(Developed > 1, "先進国", "その他"), # 上書き
Density = Population / Area) |>
# filter()の代わりにdrop_na(HDI_2018, Polity_Score) もOK
filter(!is.na(HDI_2018), !is.na(Polity_Score)) |>
group_by(Developed) |>
summarise(Density = mean(Density),
HDI = mean(HDI_2018),
Polity = mean(Polity_Score))
df2# A tibble: 2 × 4
Developed Density HDI Polity
<chr> <dbl> <dbl> <dbl>
1 その他 197. 0.695 3.92
2 先進国 174. 0.892 7.91
summarise()の結果を並び替えたいdf2を"先進国" > "その他"の順番で表示させたい。
summarise()を行う場合、グルーピング変数のアルファベット順で表示される。summarise()の前にグルーピング変数をFactor型に変換する必要がある。
DevelopedをFactor型にDeveloped列をfactor化し、要素の順番は"先進国"、"その他"の順にする。
levelsで指定した順番df |>
mutate(Developed = G7 + G20 + OECD,
Developed = if_else(Developed > 1, "先進国", "その他"),
Developed = factor(Developed, levels = c("先進国", "その他")),
Density = Population / Area) |>
filter(!is.na(HDI_2018), !is.na(Polity_Score)) |>
group_by(Developed) |>
summarise(Density = mean(Density),
HDI = mean(HDI_2018),
Polity = mean(Polity_Score))# A tibble: 2 × 4
Developed Density HDI Polity
<fct> <dbl> <dbl> <dbl>
1 先進国 174. 0.892 7.91
2 その他 197. 0.695 3.92
mutate()内にif_else()を使用
dfのOECDが1なら"OECD加盟国"、それ以外なら"OECD非加盟国"に変換し、OECD_Jという列として追加例) 変換前
例) 変換後
# A tibble: 2 × 4
OECD PPP HDI FH
<chr> <dbl> <dbl> <dbl>
1 OECD加盟国 46000. 0.894 89.1
2 OECD非加盟国 14229. 0.667 49.9
mutate()内にcase_when()を使用
.default = 新しい値は「上記の条件全てが満たされない場合の値」を意味する。例) dfのContinentを日本語にし、Continent_Jとして追加
# A tibble: 5 × 3
大陸 OECD加盟国比率 国家数
<chr> <dbl> <int>
1 アジア 0.0714 42
2 アフリカ 0 54
3 アメリカ 0.139 36
4 オセアニア 0.5 4
5 ヨーロッパ 0.54 50
例) ContinentがAP列を追加し、"Asia"か"Oceania"、"America"なら1、以外は0
方法1:if_else()の利用
方法2:case_when()の利用
方法3:case_when() + %in%の利用
NAではない欠損値もあることに注意世論調査などの場合、欠損値がNAでなく、9や99、""などの場合があるため、自分でNAに変換する必要があるケースも多い。
my_dataの例
YoungAge変数を作成し、Ageが39以下なら1、それ以外は0にする。
HighEduc2変数を作成し、HighEducが1なら"大卒以上"、それ以外は"大卒未満"にする。
NAを指定(if_else()も同様)# A tibble: 10 × 5
ID Age HighEduc YoungAge HighEduc2
<int> <dbl> <dbl> <dbl> <chr>
1 1 32 1 1 大卒以上
2 2 35 0 1 大卒未満
3 3 57 0 0 大卒未満
4 4 999 1 NA 大卒以上
5 5 74 0 0 大卒未満
6 6 66 9 0 <NA>
7 7 999 1 NA 大卒以上
8 8 49 1 0 大卒以上
9 9 78 8 0 <NA>
10 10 67 9 0 <NA>
特定の値を欠損値とし、それ以外の値は元も値にする場合
if_else()を使用し、条件に合致した場合はNAを、合致しない場合は元の変数のままにする。if_else()でなく、case_when()を使うことも可能
case_when()を使うか、OR演算子(| / %in%)を用いたif_else()を使用する。{naniar}パッケージのreplace_with_na()関数を利用
変数名 = 欠損値の値変数名 = c(値1, 値2, ...)na_if()関数mutate()における複数の処理同じ内容のコードであるため、好きな書き方で問題ないが、まとめた方が効率的
mutate()内に2つの処理mutate()内に1つの処理