Rでのデータ操作で最も重要なデータフレームの操作について解説します。 特に、dplyrパッケージにある関数群の使い方を紹介します。
dplyrパッケージの関数群によるデータフレームの操作
Rにある関数だけでも、ある程度データフレームの操作が可能です。 しかし、dplyrパッケージの関数群を用いることで、より直感的に、より柔軟にデータフレームを操作することができます。 dplyrパッケージの関数群を使いこなすことが、データ処理の技術向上の近道です。
行の操作
行を抽出するには、filter関数やslice関数などを使います。 例えば、人口が10万人以上の自治体を取り出したい場合には、filter関数が便利です。
library (dplyr)
filter (dat, population > 100000 )
# A tibble: 2 × 6
code name population pop_male pop_female households
<dbl> <chr> <dbl> <dbl> <dbl> <dbl>
1 412015 佐賀市 236372 111453 124919 93306
2 412023 唐津市 122785 57547 65238 43872
特定の行を、行番号を使って取り出したい時には、slice関数が使えます。
# A tibble: 3 × 6
code name population pop_male pop_female households
<dbl> <chr> <dbl> <dbl> <dbl> <dbl>
1 412040 多久市 19749 9146 10603 6847
2 412058 伊万里市 55238 26395 28843 19698
3 412066 武雄市 49062 23178 25884 16932
データを列の数値によって並べ替える(例えば、人口の多い順に並べ替える)にはarrange関数を使います。
arrange (dat, desc (population))
# A tibble: 20 × 6
code name population pop_male pop_female households
<dbl> <chr> <dbl> <dbl> <dbl> <dbl>
1 412015 佐賀市 236372 111453 124919 93306
2 412023 唐津市 122785 57547 65238 43872
3 412031 鳥栖市 72902 34799 38103 27630
4 412058 伊万里市 55238 26395 28843 19698
5 412066 武雄市 49062 23178 25884 16932
6 412082 小城市 44259 20823 23436 14769
7 412104 神埼市 31842 15172 16670 10913
8 412074 鹿島市 29684 13920 15764 10124
9 412091 嬉野市 27336 12667 14669 9214
10 413461 みやき町 25278 11969 13309 8638
11 414255 白石町 23941 11133 12808 7253
12 414018 有田町 20148 9356 10792 6900
13 412040 多久市 19749 9146 10603 6847
14 413411 基山町 17501 8266 9235 6321
15 413275 吉野ヶ里町 16411 8136 8275 5891
16 414247 江北町 9583 4497 5086 3225
17 413453 上峰町 9283 4379 4904 3260
18 414417 太良町 8779 4125 4654 2838
19 414239 大町町 6777 3077 3700 2560
20 413879 玄海町 5902 3035 2867 1918
desc関数は、ベクトルを降順に並べ替えるdplyrパッケージの関数で、arrange関数と一緒に使うことが多いです。
列の操作
列を抽出するには、select関数を使います。
select (dat, name, population)
# A tibble: 20 × 2
name population
<chr> <dbl>
1 佐賀市 236372
2 唐津市 122785
3 鳥栖市 72902
4 多久市 19749
5 伊万里市 55238
6 武雄市 49062
7 鹿島市 29684
8 小城市 44259
9 嬉野市 27336
10 神埼市 31842
11 吉野ヶ里町 16411
12 基山町 17501
13 上峰町 9283
14 みやき町 25278
15 玄海町 5902
16 有田町 20148
17 大町町 6777
18 江北町 9583
19 白石町 23941
20 太良町 8779
select (dat, pop_male: pop_female)
# A tibble: 20 × 2
pop_male pop_female
<dbl> <dbl>
1 111453 124919
2 57547 65238
3 34799 38103
4 9146 10603
5 26395 28843
6 23178 25884
7 13920 15764
8 20823 23436
9 12667 14669
10 15172 16670
11 8136 8275
12 8266 9235
13 4379 4904
14 11969 13309
15 3035 2867
16 9356 10792
17 3077 3700
18 4497 5086
19 11133 12808
20 4125 4654
select (dat, ! (pop_male: pop_female))
# A tibble: 20 × 4
code name population households
<dbl> <chr> <dbl> <dbl>
1 412015 佐賀市 236372 93306
2 412023 唐津市 122785 43872
3 412031 鳥栖市 72902 27630
4 412040 多久市 19749 6847
5 412058 伊万里市 55238 19698
6 412066 武雄市 49062 16932
7 412074 鹿島市 29684 10124
8 412082 小城市 44259 14769
9 412091 嬉野市 27336 9214
10 412104 神埼市 31842 10913
11 413275 吉野ヶ里町 16411 5891
12 413411 基山町 17501 6321
13 413453 上峰町 9283 3260
14 413461 みやき町 25278 8638
15 413879 玄海町 5902 1918
16 414018 有田町 20148 6900
17 414239 大町町 6777 2560
18 414247 江北町 9583 3225
19 414255 白石町 23941 7253
20 414417 太良町 8779 2838
select (dat, starts_with ("pop" ))
# A tibble: 20 × 3
population pop_male pop_female
<dbl> <dbl> <dbl>
1 236372 111453 124919
2 122785 57547 65238
3 72902 34799 38103
4 19749 9146 10603
5 55238 26395 28843
6 49062 23178 25884
7 29684 13920 15764
8 44259 20823 23436
9 27336 12667 14669
10 31842 15172 16670
11 16411 8136 8275
12 17501 8266 9235
13 9283 4379 4904
14 25278 11969 13309
15 5902 3035 2867
16 20148 9356 10792
17 6777 3077 3700
18 9583 4497 5086
19 23941 11133 12808
20 8779 4125 4654
starts_withの他に、ends_with、containsなど、類似のヘルパー関数が用意されています。
select関数を使って列名を変更することができます。
select (dat, pop = population)
# A tibble: 20 × 1
pop
<dbl>
1 236372
2 122785
3 72902
4 19749
5 55238
6 49062
7 29684
8 44259
9 27336
10 31842
11 16411
12 17501
13 9283
14 25278
15 5902
16 20148
17 6777
18 9583
19 23941
20 8779
しかし、select関数では、列名を変更した列以外が削除されてします。その他の列も残したい場合は、rename関数を使うとよいです。
rename (dat, pop = population)
# A tibble: 20 × 6
code name pop pop_male pop_female households
<dbl> <chr> <dbl> <dbl> <dbl> <dbl>
1 412015 佐賀市 236372 111453 124919 93306
2 412023 唐津市 122785 57547 65238 43872
3 412031 鳥栖市 72902 34799 38103 27630
4 412040 多久市 19749 9146 10603 6847
5 412058 伊万里市 55238 26395 28843 19698
6 412066 武雄市 49062 23178 25884 16932
7 412074 鹿島市 29684 13920 15764 10124
8 412082 小城市 44259 20823 23436 14769
9 412091 嬉野市 27336 12667 14669 9214
10 412104 神埼市 31842 15172 16670 10913
11 413275 吉野ヶ里町 16411 8136 8275 5891
12 413411 基山町 17501 8266 9235 6321
13 413453 上峰町 9283 4379 4904 3260
14 413461 みやき町 25278 11969 13309 8638
15 413879 玄海町 5902 3035 2867 1918
16 414018 有田町 20148 9356 10792 6900
17 414239 大町町 6777 3077 3700 2560
18 414247 江北町 9583 4497 5086 3225
19 414255 白石町 23941 11133 12808 7253
20 414417 太良町 8779 4125 4654 2838
新しい列を追加するにはmutate関数を使います。
mutate (dat, household_size = population / households)
# A tibble: 20 × 7
code name population pop_male pop_female households household_size
<dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 412015 佐賀市 236372 111453 124919 93306 2.53
2 412023 唐津市 122785 57547 65238 43872 2.80
3 412031 鳥栖市 72902 34799 38103 27630 2.64
4 412040 多久市 19749 9146 10603 6847 2.88
5 412058 伊万里市 55238 26395 28843 19698 2.80
6 412066 武雄市 49062 23178 25884 16932 2.90
7 412074 鹿島市 29684 13920 15764 10124 2.93
8 412082 小城市 44259 20823 23436 14769 3.00
9 412091 嬉野市 27336 12667 14669 9214 2.97
10 412104 神埼市 31842 15172 16670 10913 2.92
11 413275 吉野ヶ里町 16411 8136 8275 5891 2.79
12 413411 基山町 17501 8266 9235 6321 2.77
13 413453 上峰町 9283 4379 4904 3260 2.85
14 413461 みやき町 25278 11969 13309 8638 2.93
15 413879 玄海町 5902 3035 2867 1918 3.08
16 414018 有田町 20148 9356 10792 6900 2.92
17 414239 大町町 6777 3077 3700 2560 2.65
18 414247 江北町 9583 4497 5086 3225 2.97
19 414255 白石町 23941 11133 12808 7253 3.30
20 414417 太良町 8779 4125 4654 2838 3.09
mutate (
dat,
male_ratio = pop_male / population,
female_ratio = pop_female / population
)
# A tibble: 20 × 8
code name population pop_male pop_female households male_ratio
<dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 412015 佐賀市 236372 111453 124919 93306 0.472
2 412023 唐津市 122785 57547 65238 43872 0.469
3 412031 鳥栖市 72902 34799 38103 27630 0.477
4 412040 多久市 19749 9146 10603 6847 0.463
5 412058 伊万里市 55238 26395 28843 19698 0.478
6 412066 武雄市 49062 23178 25884 16932 0.472
7 412074 鹿島市 29684 13920 15764 10124 0.469
8 412082 小城市 44259 20823 23436 14769 0.470
9 412091 嬉野市 27336 12667 14669 9214 0.463
10 412104 神埼市 31842 15172 16670 10913 0.476
11 413275 吉野ヶ里町 16411 8136 8275 5891 0.496
12 413411 基山町 17501 8266 9235 6321 0.472
13 413453 上峰町 9283 4379 4904 3260 0.472
14 413461 みやき町 25278 11969 13309 8638 0.473
15 413879 玄海町 5902 3035 2867 1918 0.514
16 414018 有田町 20148 9356 10792 6900 0.464
17 414239 大町町 6777 3077 3700 2560 0.454
18 414247 江北町 9583 4497 5086 3225 0.469
19 414255 白石町 23941 11133 12808 7253 0.465
20 414417 太良町 8779 4125 4654 2838 0.470
# ℹ 1 more variable: female_ratio <dbl>
データフレームの結合
自治体の面積データを読み込み、先ほどのデータと結合するという操作を行いましょう。 以下のsaga2.csvをダウンロードし、dataフォルダに移動してください。
dat2 <- read_csv ("data/saga2.csv" )
Rows: 26 Columns: 3
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (1): name
dbl (2): code, area
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# A tibble: 26 × 3
code name area
<dbl> <chr> <dbl>
1 412015 佐賀市 432.
2 412023 唐津市 488.
3 412031 鳥栖市 71.7
4 412040 多久市 97.0
5 412058 伊万里市 255.
6 412066 武雄市 195.
7 412074 鹿島市 112.
8 412082 小城市 95.8
9 412091 嬉野市 126.
10 412104 神埼市 125.
# ℹ 16 more rows
これを見ると、26行のデータフレームになっています。市町のデータだけでなく、6つある郡のデータが入っているようです。このdatとdat2を結合するにはどうすればよいでしょうか。
やや泥臭いですが、dat2の中から、datに含まれる行だけを抽出し、並び順を整え、面積データだけを取り出したデータフレームdat3を作成します。 dplyrパッケージに含まれる関数を駆使しています。
dat3 <- filter (dat2, name %in% dat$ name)
dat3 <- arrange (dat3, code)
dat3 <- select (dat3, area)
dat3
# A tibble: 20 × 1
area
<dbl>
1 432.
2 488.
3 71.7
4 97.0
5 255.
6 195.
7 112.
8 95.8
9 126.
10 125.
11 44.0
12 22.2
13 12.8
14 51.9
15 35.9
16 65.8
17 11.5
18 24.5
19 99.6
20 74.3
dplyrのbind_cols関数を使って、2つのデータフレームを結合することができます。
# A tibble: 20 × 7
code name population pop_male pop_female households area
<dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 412015 佐賀市 236372 111453 124919 93306 432.
2 412023 唐津市 122785 57547 65238 43872 488.
3 412031 鳥栖市 72902 34799 38103 27630 71.7
4 412040 多久市 19749 9146 10603 6847 97.0
5 412058 伊万里市 55238 26395 28843 19698 255.
6 412066 武雄市 49062 23178 25884 16932 195.
7 412074 鹿島市 29684 13920 15764 10124 112.
8 412082 小城市 44259 20823 23436 14769 95.8
9 412091 嬉野市 27336 12667 14669 9214 126.
10 412104 神埼市 31842 15172 16670 10913 125.
11 413275 吉野ヶ里町 16411 8136 8275 5891 44.0
12 413411 基山町 17501 8266 9235 6321 22.2
13 413453 上峰町 9283 4379 4904 3260 12.8
14 413461 みやき町 25278 11969 13309 8638 51.9
15 413879 玄海町 5902 3035 2867 1918 35.9
16 414018 有田町 20148 9356 10792 6900 65.8
17 414239 大町町 6777 3077 3700 2560 11.5
18 414247 江北町 9583 4497 5086 3225 24.5
19 414255 白石町 23941 11133 12808 7253 99.6
20 414417 太良町 8779 4125 4654 2838 74.3
もっとスマートな方法があります。 それは、left_join関数を使う方法です。
Joining with `by = join_by(code, name)`
# A tibble: 20 × 7
code name population pop_male pop_female households area
<dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 412015 佐賀市 236372 111453 124919 93306 432.
2 412023 唐津市 122785 57547 65238 43872 488.
3 412031 鳥栖市 72902 34799 38103 27630 71.7
4 412040 多久市 19749 9146 10603 6847 97.0
5 412058 伊万里市 55238 26395 28843 19698 255.
6 412066 武雄市 49062 23178 25884 16932 195.
7 412074 鹿島市 29684 13920 15764 10124 112.
8 412082 小城市 44259 20823 23436 14769 95.8
9 412091 嬉野市 27336 12667 14669 9214 126.
10 412104 神埼市 31842 15172 16670 10913 125.
11 413275 吉野ヶ里町 16411 8136 8275 5891 44.0
12 413411 基山町 17501 8266 9235 6321 22.2
13 413453 上峰町 9283 4379 4904 3260 12.8
14 413461 みやき町 25278 11969 13309 8638 51.9
15 413879 玄海町 5902 3035 2867 1918 35.9
16 414018 有田町 20148 9356 10792 6900 65.8
17 414239 大町町 6777 3077 3700 2560 11.5
18 414247 江北町 9583 4497 5086 3225 24.5
19 414255 白石町 23941 11133 12808 7253 99.6
20 414417 太良町 8779 4125 4654 2838 74.3
この関数は、2つのデータフレームから共通の名前を持つ列を探して、それらの列の値をキーにして、自動的に2つのデータフレームを結合します。
left_joinの他にも、inner_join、right_join、full_joinといった類似の関数が用意されています。それぞれどのように異なるのか、RStudioのヘルプ機能を使って調べてみましょう。