統計データ解析I

第4講 練習問題 解答例

Published

May 9, 2025

準備

以下で利用する共通パッケージを読み込む.

library(conflicted)  # 関数名の衝突を警告
conflicts_prefer(    # 優先的に使う関数を指定
    dplyr::filter(),
    dplyr::select(),
    dplyr::lag(),
    )
library(tidyverse)

データフレームの操作

問題

datasets::airquality に対して以下の条件を満たすデータを取り出しなさい.

  • 7月のオゾン濃度 (Ozone)

  • 風速 (Wind) が時速10マイル以上で,かつ気温 (Temp) が華氏80度以上の日のデータ

  • オゾン (Ozone) も日射量 (Solar.R) も欠測 (NA) でないデータの月 (Month) と日 (Day)

解答例

datasets::airqualitytibble 形式に変換する.

aq_tbl <- as_tibble(airquality) # tibble 形式へ変換

7月のオゾン濃度のデータを取り出す.

aq_tbl |>
    filter(Month == 7) |> # Month %in% 7 などとしても良い
    select(Ozone)
# A tibble: 31 × 1
   Ozone
   <int>
 1   135
 2    49
 3    32
 4    NA
 5    64
 6    40
 7    77
 8    97
 9    97
10    85
# ℹ 21 more rows

風速時速10マイル以上かつ気温が華氏80度以上のデータを取り出す.

aq_tbl |>
    filter(Wind >= 10 & Temp >= 80)
# A tibble: 24 × 6
   Ozone Solar.R  Wind  Temp Month   Day
   <int>   <int> <dbl> <int> <int> <int>
 1    45     252  14.9    81     5    29
 2    71     291  13.8    90     6     9
 3    39     323  11.5    87     6    10
 4    NA     259  10.9    93     6    11
 5    NA     332  13.8    80     6    14
 6    NA      98  11.5    80     6    28
 7    NA     101  10.9    84     7     4
 8    40     314  10.9    83     7     6
 9    27     175  14.9    81     7    13
10    NA     291  14.9    91     7    14
# ℹ 14 more rows

日射量が欠測でないデータの月と日を取り出す.

aq_tbl |>
    filter(!is.na(Ozone) & !is.na(Solar.R)) |>
    select(Month,Day) # 書いた順に並ぶ
# A tibble: 111 × 2
   Month   Day
   <int> <int>
 1     5     1
 2     5     2
 3     5     3
 4     5     4
 5     5     7
 6     5     8
 7     5     9
 8     5    12
 9     5    13
10     5    14
# ℹ 101 more rows
aq_tbl |>
    filter(!is.na(Ozone) & !is.na(Solar.R)) |>
    select(Month:Day) # もともと並んでいるので c(Month,Day) と同じ
# A tibble: 111 × 2
   Month   Day
   <int> <int>
 1     5     1
 2     5     2
 3     5     3
 4     5     4
 5     5     7
 6     5     8
 7     5     9
 8     5    12
 9     5    13
10     5    14
# ℹ 101 more rows

データの読み込みと操作

問題

サンプルデータ (jpdata) を読み込んで操作しなさい.

Note

https://www.e-stat.go.jp より取得したデータ (文字コード : utf8)

  • jpdata1.csv : 県別の対象データ
  • jpdata2.csv : 対象データの内容説明
  • jpdata3.csv : 県と地域の対応関係

(地域から探す / 全県を選択 / 項目を選択してダウンロード)

  • 作業ディレクトリ内にサブディレクトリ data を作成し,その中に置いて読み込む.

    jp_data <- read_csv(file = "data/jpdata1.csv")
    jp_item <- read_csv(file = "data/jpdata2.csv")
    jp_area <- read_csv(file = "data/jpdata3.csv")

    日本語に問題がある場合は英語版を読み込む.

    jp_data_en <- read_csv(file = "data/jpdata1-en.csv")
    jp_area_en <- read_csv(file = "data/jpdata3-en.csv")

解答例

ファイルからデータを読み込む.

jp_data <- read_csv(file = "data/jpdata1.csv")
jp_item <- read_csv(file = "data/jpdata2.csv")
jp_area <- read_csv(file = "data/jpdata3.csv")
Note

文字コードは関数 readr::guess_encoding() により推測される.

guess_encoding("data/jpdata1.csv")

以下にデータ操作の例を示す.

#' 項目名の内容を確認
jp_item
# A tibble: 7 × 3
  列名  内容                                     データ番号
  <chr> <chr>                                    <chr>     
1 人口  総人口【人】                             A1101     
2 若年  15歳未満人口【人】                     A1301     
3 老人  65歳以上人口【人】                     A1303     
4 面積  総面積(北方地域及び竹島を除く)【ha】 B1101     
5 婚姻  婚姻率(人口千人当たり)【‐】            #A06601   
6 離婚  離婚率(人口千人当たり)【‐】            #A06602   
7 失業  完全失業率【%】                         #F01301   
#' 最初の10県を表示
head(jp_data, n = 10) 
# A tibble: 10 × 8
   県名      人口   若年    老人    面積  婚姻  離婚  失業
   <chr>    <dbl>  <dbl>   <dbl>   <dbl> <dbl> <dbl> <dbl>
 1 北海道 5320000 588000 1632000 7842078  4.5   1.91   4.6
 2 青森県 1278000 141000  407000  964564  4.01  1.64   5.3
 3 岩手県 1255000 144000  400000 1527501  3.8   1.48   4  
 4 宮城県 2323000 280000  631000  728222  4.58  1.61   4.9
 5 秋田県  996000 101000  354000 1163752  3.32  1.37   4.3
 6 山形県 1102000 130000  355000  932315  3.91  1.32   3.6
 7 福島県 1882000 220000  569000 1378390  4.29  1.7    4.4
 8 茨城県 2892000 355000  819000  609719  4.42  1.62   4.5
 9 栃木県 1957000 245000  536000  640809  4.49  1.64   4.3
10 群馬県 1960000 241000  567000  636228  4.25  1.61   4.3
#' 最後の10県を表示
tail(jp_data, n = 10)
# A tibble: 10 × 8
   県名        人口   若年    老人   面積  婚姻  離婚  失業
   <chr>      <dbl>  <dbl>   <dbl>  <dbl> <dbl> <dbl> <dbl>
 1 愛媛県   1364000 164000  437000 567623  4.14  1.7    4.4
 2 高知県    714000  80000  244000 710386  4.02  1.78   4.9
 3 福岡県   5107000 675000 1384000 498652  5.07  1.88   5.3
 4 佐賀県    824000 113000  240000 244068  4.42  1.56   4.1
 5 長崎県   1354000 173000  424000 413088  4.31  1.54   4.4
 6 熊本県   1765000 237000  531000 740948  4.47  1.62   4.5
 7 大分県   1152000 143000  367000 634073  4.36  1.69   4.5
 8 宮崎県   1089000 146000  338000 773532  4.3   1.96   4.6
 9 鹿児島県 1626000 217000  501000 918701  4.39  1.7    4.7
10 沖縄県   1443000 247000  303000 228098  5.6   2.41   6.3
#' 地方名を確認
View(jp_area) # 左上ペインに表として表示される
#' 人口の最大値を見る
with(jp_data, max(人口))
[1] 13724000
#' どの都道府県の人口多いか調べる ('?which.max' を参照)
with(jp_data, which.max(人口)) # 行番号が返る
[1] 13
jp_data[with(jp_data, which.max(人口)),]
# A tibble: 1 × 8
  県名       人口    若年    老人   面積  婚姻  離婚  失業
  <chr>     <dbl>   <dbl>   <dbl>  <dbl> <dbl> <dbl> <dbl>
1 東京都 13724000 1542000 3160000 219396  6.19  1.68   3.9
#' 行を抽出するには関数 dplyr::filter() を使うのが簡単
jp_data |> filter(人口 == max(人口))
# A tibble: 1 × 8
  県名       人口    若年    老人   面積  婚姻  離婚  失業
  <chr>     <dbl>   <dbl>   <dbl>  <dbl> <dbl> <dbl> <dbl>
1 東京都 13724000 1542000 3160000 219396  6.19  1.68   3.9
#' 人口の多い順に都道府県を並べる ('?order' を参照)
with(jp_data, order(人口, decreasing = TRUE)) # 行番号を取得
 [1] 13 14 27 23 11 12 28  1 40 22  8 34 26  4 15 20 21 10  9 33  7 24 43 46 47
[26] 25 35 38 42 29  2  3 44 17  6 45 16  5 37 30 41 19 18 36 39 32 31
jp_data[with(jp_data, order(人口, decreasing = TRUE)),] # 並べ替え
# A tibble: 47 × 8
   県名         人口    若年    老人    面積  婚姻  離婚  失業
   <chr>       <dbl>   <dbl>   <dbl>   <dbl> <dbl> <dbl> <dbl>
 1 東京都   13724000 1542000 3160000  219396  6.19  1.68   3.9
 2 神奈川県  9159000 1122000 2274000  241617  5.05  1.68   3.9
 3 大阪府    8823000 1069000 2399000  190514  5.15  1.92   5.3
 4 愛知県    7525000 1010000 1852000  517292  5.33  1.66   3.4
 5 埼玉県    7310000  899000 1900000  379775  4.61  1.66   4.3
 6 千葉県    6246000  755000 1692000  515761  4.59  1.66   4.1
 7 兵庫県    5503000  692000 1558000  840094  4.63  1.66   4.6
 8 北海道    5320000  588000 1632000 7842078  4.5   1.91   4.6
 9 福岡県    5107000  675000 1384000  498652  5.07  1.88   5.3
10 静岡県    3675000  464000 1069000  777742  4.51  1.63   4  
# ℹ 37 more rows
with(jp_data, 県名[order(人口, decreasing = TRUE)]) # 県名のみを表示
 [1] "東京都"   "神奈川県" "大阪府"   "愛知県"   "埼玉県"   "千葉県"  
 [7] "兵庫県"   "北海道"   "福岡県"   "静岡県"   "茨城県"   "広島県"  
[13] "京都府"   "宮城県"   "新潟県"   "長野県"   "岐阜県"   "群馬県"  
[19] "栃木県"   "岡山県"   "福島県"   "三重県"   "熊本県"   "鹿児島県"
[25] "沖縄県"   "滋賀県"   "山口県"   "愛媛県"   "長崎県"   "奈良県"  
[31] "青森県"   "岩手県"   "大分県"   "石川県"   "山形県"   "宮崎県"  
[37] "富山県"   "秋田県"   "香川県"   "和歌山県" "佐賀県"   "山梨県"  
[43] "福井県"   "徳島県"   "高知県"   "島根県"   "鳥取県"  
#' 行を並べ替えるには関数 dplyr::arrange() を使うのが簡単 
jp_data |> arrange(desc(人口)) |> print(n = Inf) # ('?dplyr::desc' を参照)
# A tibble: 47 × 8
   県名         人口    若年    老人    面積  婚姻  離婚  失業
   <chr>       <dbl>   <dbl>   <dbl>   <dbl> <dbl> <dbl> <dbl>
 1 東京都   13724000 1542000 3160000  219396  6.19  1.68   3.9
 2 神奈川県  9159000 1122000 2274000  241617  5.05  1.68   3.9
 3 大阪府    8823000 1069000 2399000  190514  5.15  1.92   5.3
 4 愛知県    7525000 1010000 1852000  517292  5.33  1.66   3.4
 5 埼玉県    7310000  899000 1900000  379775  4.61  1.66   4.3
 6 千葉県    6246000  755000 1692000  515761  4.59  1.66   4.1
 7 兵庫県    5503000  692000 1558000  840094  4.63  1.66   4.6
 8 北海道    5320000  588000 1632000 7842078  4.5   1.91   4.6
 9 福岡県    5107000  675000 1384000  498652  5.07  1.88   5.3
10 静岡県    3675000  464000 1069000  777742  4.51  1.63   4  
11 茨城県    2892000  355000  819000  609719  4.42  1.62   4.5
12 広島県    2829000  368000  809000  847963  4.66  1.63   3.7
13 京都府    2599000  308000  743000  461220  4.57  1.58   4.4
14 宮城県    2323000  280000  631000  728222  4.58  1.61   4.9
15 新潟県    2267000  265000  709000 1258415  3.93  1.28   3.7
16 長野県    2076000  260000  647000 1356156  4.32  1.55   3.4
17 岐阜県    2008000  258000  589000 1062129  4.18  1.48   3.4
18 群馬県    1960000  241000  567000  636228  4.25  1.61   4.3
19 栃木県    1957000  245000  536000  640809  4.49  1.64   4.3
20 岡山県    1907000  243000  567000  711432  4.63  1.7    4.1
21 福島県    1882000  220000  569000 1378390  4.29  1.7    4.4
22 三重県    1800000  226000  522000  577441  4.41  1.55   3.4
23 熊本県    1765000  237000  531000  740948  4.47  1.62   4.5
24 鹿児島県  1626000  217000  501000  918701  4.39  1.7    4.7
25 沖縄県    1443000  247000  303000  228098  5.6   2.41   6.3
26 滋賀県    1413000  200000  357000  401738  4.66  1.56   3.5
27 山口県    1383000  164000  462000  611253  4.11  1.59   4  
28 愛媛県    1364000  164000  437000  567623  4.14  1.7    4.4
29 長崎県    1354000  173000  424000  413088  4.31  1.54   4.4
30 奈良県    1348000  163000  408000  369094  4.07  1.52   4.9
31 青森県    1278000  141000  407000  964564  4.01  1.64   5.3
32 岩手県    1255000  144000  400000 1527501  3.8   1.48   4  
33 大分県    1152000  143000  367000  634073  4.36  1.69   4.5
34 石川県    1147000  145000  331000  418605  4.51  1.34   3.4
35 山形県    1102000  130000  355000  932315  3.91  1.32   3.6
36 宮崎県    1089000  146000  338000  773532  4.3   1.96   4.6
37 富山県    1056000  124000  334000  424761  4.13  1.32   3.1
38 秋田県     996000  101000  354000 1163752  3.32  1.37   4.3
39 香川県     967000  120000  301000  187677  4.46  1.74   4  
40 和歌山県   945000  112000  304000  472464  4.28  1.81   4.5
41 佐賀県     824000  113000  240000  244068  4.42  1.56   4.1
42 山梨県     823000   99000  245000  446527  4.39  1.67   4.4
43 福井県     779000  101000  232000  419051  4.34  1.39   3.3
44 徳島県     743000   85000  241000  414680  4.02  1.57   5  
45 高知県     714000   80000  244000  710386  4.02  1.78   4.9
46 島根県     685000   85000  230000  670806  3.89  1.51   2.9
47 鳥取県     565000   72000  175000  350713  4.27  1.58   3.9

上記と同じ内容を英語版のデータで実行する場合は以下のようになる.

jp_data_en <- read_csv(file="data/jpdata1-en.csv")
jp_area_en <- read_csv(file="data/jpdata3-en.csv")
#' データを確認する
head(jp_data_en, n = 10) 
# A tibble: 10 × 8
   prefecture population young_population old_population   area marriage divorce
   <chr>           <dbl>            <dbl>          <dbl>  <dbl>    <dbl>   <dbl>
 1 Hokkaido      5320000           588000        1632000 7.84e6     4.5     1.91
 2 Aomori        1278000           141000         407000 9.65e5     4.01    1.64
 3 Iwate         1255000           144000         400000 1.53e6     3.8     1.48
 4 Miyagi        2323000           280000         631000 7.28e5     4.58    1.61
 5 Akita          996000           101000         354000 1.16e6     3.32    1.37
 6 Yamagata      1102000           130000         355000 9.32e5     3.91    1.32
 7 Fukushima     1882000           220000         569000 1.38e6     4.29    1.7 
 8 Ibaraki       2892000           355000         819000 6.10e5     4.42    1.62
 9 Tochigi       1957000           245000         536000 6.41e5     4.49    1.64
10 Gunma         1960000           241000         567000 6.36e5     4.25    1.61
# ℹ 1 more variable: unemployed <dbl>
tail(jp_data_en, n = 10)
# A tibble: 10 × 8
   prefecture population young_population old_population   area marriage divorce
   <chr>           <dbl>            <dbl>          <dbl>  <dbl>    <dbl>   <dbl>
 1 Ehime         1364000           164000         437000 567623     4.14    1.7 
 2 Kochi          714000            80000         244000 710386     4.02    1.78
 3 Fukuoka       5107000           675000        1384000 498652     5.07    1.88
 4 Saga           824000           113000         240000 244068     4.42    1.56
 5 Nagasaki      1354000           173000         424000 413088     4.31    1.54
 6 Kumamoto      1765000           237000         531000 740948     4.47    1.62
 7 Oita          1152000           143000         367000 634073     4.36    1.69
 8 Miyazaki      1089000           146000         338000 773532     4.3     1.96
 9 Kagoshima     1626000           217000         501000 918701     4.39    1.7 
10 Okinawa       1443000           247000         303000 228098     5.6     2.41
# ℹ 1 more variable: unemployed <dbl>
View(jp_area_en)
#' 人口の最大値を見る
with(jp_data_en, max(population))
[1] 13724000
#' 人口の最大値を与える県の番号を見る
with(jp_data_en, which.max(population))
[1] 13
#' どの都道府県の人口多いか調べる
jp_data_en |> filter(population == max(population))
# A tibble: 1 × 8
  prefecture population young_population old_population   area marriage divorce
  <chr>           <dbl>            <dbl>          <dbl>  <dbl>    <dbl>   <dbl>
1 Tokyo        13724000          1542000        3160000 219396     6.19    1.68
# ℹ 1 more variable: unemployed <dbl>
#' 人口の多い順に都道府県を並べる
jp_data_en |> arrange(desc(population)) |> View()

データの集計

問題

以下の指示に従ってサンプルデータ (jpdata) を整理しなさい.

  • 県別の人口密度を求めよ.

  • 地方別の人口密度を求めよ.

    Warning

    県ごとに人口が異なるので単純に人口密度を平均してはいけない.

  • 地方別の1000人当たりの婚姻・離婚数を概算せよ. なお,データの記述では「人口1000人当たり」とあるが,この「人口」とは若年層は婚姻不可として除いた「婚姻可能な人口1000人当たり」と考えて計算しなさい.

解答例

県別の人口密度 (人口/面積) を求める.

with(jp_data, 人口/面積) # 値のみ返す
 [1]  0.6783916  1.3249510  0.8216034  3.1899613  0.8558524  1.1820039
 [7]  1.3653610  4.7431686  3.0539521  3.0806566 19.2482391 12.1102604
[13] 62.5535561 37.9071009  1.8014725  2.4861040  2.7400533  1.8589623
[19]  1.8431136  1.5307973  1.8905425  4.7252174 14.5469097  3.1172016
[25]  3.5172177  5.6350549 46.3115572  6.5504574  3.6521862  2.0001524
[31]  1.6110039  1.0211596  2.6805092  3.3362305  2.2625656  1.7917430
[37]  5.1524694  2.4030034  1.0050874 10.2416114  3.3761083  3.2777520
[43]  2.3820835  1.8168255  1.4078280  1.7698903  6.3262282

都道府県別の人口密度を求める.

jp_data |>
    select(県名, 人口, 面積) |>  # 県名,人口,面積を選択
    mutate(人口密度 = 人口/面積) # 人口密度を計算
# A tibble: 47 × 4
   県名      人口    面積 人口密度
   <chr>    <dbl>   <dbl>    <dbl>
 1 北海道 5320000 7842078    0.678
 2 青森県 1278000  964564    1.32 
 3 岩手県 1255000 1527501    0.822
 4 宮城県 2323000  728222    3.19 
 5 秋田県  996000 1163752    0.856
 6 山形県 1102000  932315    1.18 
 7 福島県 1882000 1378390    1.37 
 8 茨城県 2892000  609719    4.74 
 9 栃木県 1957000  640809    3.05 
10 群馬県 1960000  636228    3.08 
# ℹ 37 more rows

地方別の人口密度 (地方の総人口/地方の総面積) を求める.

jp_data |>
    mutate(地方 = as_factor(jp_area[["地方"]])) |> # 地方の情報を付加
    group_by(地方) |>                              # 地方ごとにグループ化
    summarize((across(c(人口, 面積), sum))) |>     # 地方ごとに人口と面積を集計
    mutate(人口密度 = 人口/面積)                   # 地方別の人口密度を計算
# A tibble: 8 × 4
  地方       人口    面積 人口密度
  <fct>     <dbl>   <dbl>    <dbl>
1 北海道  5320000 7842078    0.678
2 東北    8836000 6694744    1.32 
3 関東   43248000 3243305   13.3  
4 中部   21356000 6680678    3.20 
5 近畿   22431000 3312565    6.77 
6 中国    7369000 3192167    2.31 
7 四国    3788000 1880366    2.01 
8 九州   14360000 4451160    3.23 

地方別の婚姻・離婚数(1000人あたり)を求める.

jp_data |>
    mutate(婚姻可能 = 人口-若年,                   # 婚姻可能な人口を推計 
           婚姻数 = 婚姻可能*婚姻/1000,            # 婚姻数/1000人から人数を推計
           離婚数 = 婚姻可能*離婚/1000,            # 離婚数/1000人から人数を推計
           地方 = as_factor(jp_area[["地方"]])) |> # 地方の情報を付加
    group_by(地方) |>                              # 地方ごとにグループ化
    summarize((across(婚姻可能:離婚数, sum))) |>   # 地方別の合計を計算
    mutate(婚姻 = 婚姻数/婚姻可能*1000,            # 1000人あたりの婚姻数を計算
           離婚 = 離婚数/婚姻可能*1000)            # 1000人あたりの離婚数を計算
# A tibble: 8 × 6
  地方   婚姻可能  婚姻数 離婚数  婚姻  離婚
  <fct>     <dbl>   <dbl>  <dbl> <dbl> <dbl>
1 北海道  4732000  21294   9038.  4.5   1.91
2 東北    7820000  32040. 12133.  4.10  1.55
3 関東   38089000 196958  63410.  5.17  1.66
4 中部   18630000  86724. 28741.  4.66  1.54
5 近畿   19661000  93660. 34135.  4.76  1.74
6 中国    6437000  28622. 10463.  4.45  1.63
7 四国    3339000  13939.  5675.  4.17  1.70
8 九州   12409000  58870. 22567.  4.74  1.82
Tip

日本語の扱いで不具合がある場合は

  • jp_data -> jp_data_en
  • 人口 -> population
  • 若年 -> young_population
  • 婚姻 -> marriage
  • 離婚 -> divorce

など書き換えて試してみて下さい.