データフレームの操作

公開

2026年4月24日

更新日

2026年4月24日

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関数が使えます。

slice(dat, 4:6)
# 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_withcontainsなど、類似のヘルパー関数が用意されています。

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.
dat2
# 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つある郡のデータが入っているようです。このdatdat2を結合するにはどうすればよいでしょうか。

やや泥臭いですが、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

dplyrbind_cols関数を使って、2つのデータフレームを結合することができます。

bind_cols(dat, dat3)
# 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関数を使う方法です。

left_join(dat, dat2)
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_joinright_joinfull_joinといった類似の関数が用意されています。それぞれどのように異なるのか、RStudioのヘルプ機能を使って調べてみましょう。