2 Excelファイルの読み込み
2.1 一つのExcelファイルを読み込む
2.1.1 ファイルの準備と読み込み
ExcelファイルをRに読み込むには、readxl
パッケージが便利です。7セクション1.2で述べた通り、ここからは、githubレポジトリのhttps://github.com/izunyan/excel_r をダウンロードしてプロジェクトを開いて進めてみてください。dataフォルダ(data/
で表現)に入っている「ペンギン.xlsx」8を読み込んでみましょう。
読み込みにはread_xlsx()
関数を使います。したがって、以下すべてExcelファイル形式は.xlsx
を想定します。read_xls()
やread_excel()
という関数もあるので、ファイル形式によって使い分けられます。ファイル形式が混ざっている時はread_excel()
が有用かもしれません。
## # A tibble: 344 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデリー Torgers… 39.1 18.7 181 3750 male
## 2 Adelie アデリー Torgers… 39.5 17.4 186 3800 fema…
## 3 Adelie アデリー Torgers… 40.3 18 195 3250 fema…
## # … with 341 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
上記コードを実行すると、RStudioの右上(デフォルトの配置であれば)のEnvironmentタブに、
df 344 obs. of 9 variables
という表示が出ると思います。つまり、344行のデータと9列の変数が入っているデータを、df
という名前のもの(オブジェクト)としてRに読みこんだ、ということを示しています。df <-
の部分がその作業に該当します。<-
の右側の内容を左側のオブジェクトに格納するという意味です。ここで読み込まれた形がデータフレーム(はじめに>本書の構成の注参照)です。
オブジェクト名であるdf
と打つことで、デフォルトでは最初の10行分のデータが表示されます。ここでは紙面の都合で設定を変えているので3行だけにしています。表示された最初の行にも、A tibble: 344 x 9
と、行数x列数の情報が出ています。表示しきれなかった行は、with 341 more rows
と省略され、表示しきれなかった列は、flipper_length_mm <dbl>, body_mass_g <dbl>, sex <chr>, year <dbl>
と、名前<データの型名>
が表示されます。なお、読みこんだファイルの保存については3.1章で解説します。
2.1.1.1 最高な機能だよ!パスの自動補完
read_xlsx("")
と打った後に、" "
の中にカーソルを置いて、tabキーを押すと、プロジェクトの中身が一覧で表示されるので、選んでいくだけで目的のファイルがキーボードを打つことなしに選べます!RStudioは" "
と打てばどこでもこの補完が可能です。9
上の階層のフォルダに行きたいときは、" "
の中に../
と打てば可能です。その後にtabキーを押せば上の階層のフォルダが選べます。
2.1.2 列名(変数名)がひどい場合の読み込み
read_xlsx("data/ペンギン(ひどい列名)ver.xlsx")
## # A tibble: 344 × 9
## Spe…¹ `種 類` ※島…² ①クチ…³ ②クチバ…⁴ 翼:…⁵ ■体重…⁶ `㊛㊚`
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデリー Torger… 39.1 18.7 181 3750 male
## 2 Adelie アデリー Torger… 39.5 17.4 186 3800 female
## 3 Adelie アデリー Torger… 40.3 18 195 3250 female
## # … with 341 more rows, 1 more variable:
## # `2007~2009` <dbl>, and abbreviated variable names
## # ¹Species, ²`※島の名前`, ³`①クチバシ 長さ(mm)`,
## # ⁴`②クチバシ_大きさ(mm)`, ⁵`翼:長さ(mm)`,
## # ⁶`■体重 単位はg`
読めることは読めますが、今後のデータ処理を進めるうえで不安が残ります。
2.1.2.1 スペースや記号などを自動的に変換してくれる関数できれいに
janitor
パッケージのclean_names()
関数を使って、列名に入り込んでいるスペースや記号などを安全な記号に変換します。
なお、日本語の列名では、clean_names()
関数にcase = "old_janitor"
をつけないと読みにくい結果になります。このように、関数の中に追加する情報のことを引数(ひきすう)と言います。引数によってさまざまな条件を変更することが可能になります。
read_xlsx("data/ペンギン(ひどい列名)ver.xlsx") |>
clean_names(case = "old_janitor")
## # A tibble: 344 × 9
## speci…¹ 種_類 x_島…² x_ク…³ x_クチバ…⁴ 翼_長…⁵ x_体…⁶ x
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデ… Torger… 39.1 18.7 181 3750 male
## 2 Adelie アデ… Torger… 39.5 17.4 186 3800 female
## 3 Adelie アデ… Torger… 40.3 18 195 3250 female
## # … with 341 more rows, 1 more variable:
## # 2007_2009 <dbl>, and abbreviated variable names
## # ¹species, ²x_島の名前, ³x_クチバシ_長さ_mm,
## # ⁴x_クチバシ_大きさ_mm, ⁵翼_長さ_mm, ⁶x_体重_単位はg
さて、ここで使われている |>
は非常に大事なので解説しておきます。
2.1.2.2 |> とは?
「パイプ」と読みます10。処理を重ねてコードに書いていきたい際に重宝し、現代のtidyverse
を使ったRのコードに欠かせないものです。まずtidyverse
パッケージを読み込みます
たとえば、データフレームdfのspecies列を選択する、という処理の
select(df, species)
は
df |> select(species)
と書けます。 |>
の左側にあるものを右側の最初の部分(第1引数)に渡すという働きです。パイプの利点は、いくつもつないで書いていけることです。たとえば、ペンギンの種類別にクチバシの長さの平均値を出したいときには次のようにできます。
## # A tibble: 3 × 2
## species 平均値
## <chr> <dbl>
## 1 Adelie 38.8
## 2 Chinstrap 48.8
## 3 Gentoo 47.5
以下では|>
を多用していきます。
なお、ショートカットctrl + shit + M
(MacだとCmd + Shift + M
)で出せます11。
2.1.2.3 全角←→半角を自動で
stringi
パッケージのstri_trans_nfkc()
関数を使って、変数名で全角-半角のばらつきを統一させます。stringi
パッケージは本書ではここでしか使わないので,一時的にパッケージから関数を呼び出す処理としてパッケージ名::関数名()
を使います。
read_xlsx("data/ペンギン(ひどい列名)ver.xlsx") |>
rename_with(~stringi::stri_trans_nfkc(.))
## # A tibble: 344 × 9
## Species `種 類` ※島の…¹ 1クチ…² 2クチ…³ 翼:長…⁴ ■体…⁵ 女男
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデリー Torgers… 39.1 18.7 181 3750 male
## 2 Adelie アデリー Torgers… 39.5 17.4 186 3800 female
## 3 Adelie アデリー Torgers… 40.3 18 195 3250 female
## # … with 341 more rows, 1 more variable: `2007~2009` <dbl>, and
## # abbreviated variable names ¹`※島の名前`,
## # ²`1クチバシ 長さ(mm)`, ³`2クチバシ_大きさ(mm)`,
## # ⁴`翼:長さ(mm)`, ⁵`■体重 単位はg`
ここでは、変数名をリネームするのにdplyr 1.0.0
で登場したrename_with()
関数を使いました。デフォルトで全列対象の.cols = everything()
という引数が含められているので、すべての変数に対し、全角文字を含んでいたら半角に直すというコードになります。
2.1.2.4 上記の合わせ技
|>
でつなぎ合わせて1つの実行で合わせてしまうこともできます。
read_xlsx("data/ペンギン(ひどい列名)ver.xlsx") |>
rename_with(~stringi::stri_trans_nfkc(.)) |>
clean_names(case = "old_janitor")
## # A tibble: 344 × 9
## species 種_類 x_島の…¹ x1ク…² x2クチ…³ 翼_長…⁴ x_体…⁵ 女男
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデリー Torgers… 39.1 18.7 181 3750 male
## 2 Adelie アデリー Torgers… 39.5 17.4 186 3800 female
## 3 Adelie アデリー Torgers… 40.3 18 195 3250 female
## # … with 341 more rows, 1 more variable: x2007_2009 <dbl>, and
## # abbreviated variable names ¹x_島の名前, ²x1クチバシ_長さ_mm,
## # ³x2クチバシ_大きさ_mm, ⁴翼_長さ_mm, ⁵x_体重_単位はg
2.1.3 開始行を指定して読み込む
理想的なデータは1行目に列名が入力されている形ですが、最初の数行が空だったり、文字の説明が入っていたりすることも多いです。そうした場合は、以下のような読み込み結果になります。
## # A tibble: 346 × 3
## ...1 ここに説明とか書いてあるファイル読むのつらいの…¹ ...3
## <chr> <chr> <chr>
## 1 <NA> <NA> <NA>
## 2 species island bill_…
## 3 Adelie Torgersen 39.1
## # … with 343 more rows, and abbreviated variable name
## # ¹ここに説明とか書いてあるファイル読むのつらいのです
列名が、セルに内容が入っている行から始まり、他の列名が...1
, ...3
といったものになりました。そしてデータがうまく読み込めていません。これを、指定した行から読み込むには、引数skip =
にとばしたい行の数を指定します。
read_xlsx("data/ペンギン(3行空き).xlsx", skip = 3)
## # A tibble: 344 × 9
## species island bill_le…¹ bill_…² flipp…³ body_…⁴ sex year
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
## 1 Adelie Torgersen 39.1 18.7 181 3750 male 2007
## 2 Adelie Torgersen 39.5 17.4 186 3800 fema… 2007
## 3 Adelie Torgersen 40.3 18 195 3250 fema… 2007
## # … with 341 more rows, 1 more variable: 種類 <chr>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
このように、ちゃんと読む込むことができました。
2.1.4 セルを指定して読み込む
引数range =
にセル範囲を指定すれば、そのセル範囲だけを読み込むこともできます。
read_xlsx("data/ペンギン.xlsx", range = "A1:D5")
## # A tibble: 4 × 4
## species 種類 island bill_length_mm
## <chr> <chr> <chr> <dbl>
## 1 Adelie アデリー Torgersen 39.1
## 2 Adelie アデリー Torgersen 39.5
## 3 Adelie アデリー Torgersen 40.3
## 4 Adelie アデリー Torgersen NA
他にも、cell_cols =
で読みたい列の指定、cell_rows =
で読みたい行の指定も行えます。
2.2 シートを指定して読み込む
2.2.1 シート名の確認
複雑なExcelファイルとなると、たくさんのシートが含まれていて、その全容を知るのも一苦労です。Rでは、readxl
パッケージのexcel_sheets()
関数でシート名の一覧を簡単に取得できます。
excel_sheets("data/ペンギン(シート別).xlsx")
## [1] "アデリー" "ジェンツー" "ヒゲ"
2.2.2 普通の読み込み
シートが分かれているExcelファイルをそのまま読みこんでみます。
read_xlsx("data/ペンギン(シート別).xlsx")
## # A tibble: 152 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデリー Torgers… 39.1 18.7 181 3750 male
## 2 Adelie アデリー Torgers… 39.5 17.4 186 3800 fema…
## 3 Adelie アデリー Torgers… 40.3 18 195 3250 fema…
## # … with 149 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
デフォルトでは一番最初のシートのデータが読みこまれます。ここでは、シート「アデリー」が読み込まれました。
2.2.3 シートを指定した読み込み
引数のsheet =
にシート名を指定することで読み込めます。
read_excel("data/ペンギン(シート別).xlsx", sheet = "ジェンツー" )
## # A tibble: 124 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Gentoo ジェンツー Biscoe 46.1 13.2 211 4500 fema…
## 2 Gentoo ジェンツー Biscoe 50 16.3 230 5700 male
## 3 Gentoo ジェンツー Biscoe 48.7 14.1 210 4450 fema…
## # … with 121 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
2.2.4 すべてのシートから一気に読み込み
今まで身につけた知識を使うと、すべてのシートからデータを読みたいときは、単純に
df_Adelie <-
read_excel("data/ペンギン(シート別).xlsx", sheet = "アデリー" )
df_Gentoo <-
read_excel("data/ペンギン(シート別).xlsx", sheet = "ジェンツー" )
df_Chinstrap <-
read_excel("data/ペンギン(シート別).xlsx", sheet = "ヒゲ" )
と1つずつ読み込めばよいとわかります。しかし、これが100シート分あったら読むだけで多くの時間がかかり、うんざりしてしまうでしょう。また、疲労によりミスも起こるかもしれません。コードも長くて読みにくくなってしまいます。そんな時に便利で正確で短くコードが書ける素敵な方法があるのです。おそらくこれを知って使えるようになることが、初心者から中級者への第一歩になるのではないでしょうか。
ここで一気にレベルが上がりますが、これこそがRを使ってExcelファイルを読み込む便利な部分(その用途に限らず、コード書いてコンピュータに働いてもらうの最高!ってなる部分)なので、その魅力をみていきましょう。
path_name <- "data/ペンギン(シート別).xlsx" # データのパスを格納
# シート名を取得しそれぞれから読み込んでリストにまとめる
df_list <-
excel_sheets(path_name) |>
set_names() |> # 名前付きベクトルにする
map(read_excel, path = path_name)
df_list # 作成したリストの表示
## $アデリー
## # A tibble: 152 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデリー Torgers… 39.1 18.7 181 3750 male
## 2 Adelie アデリー Torgers… 39.5 17.4 186 3800 fema…
## 3 Adelie アデリー Torgers… 40.3 18 195 3250 fema…
## # … with 149 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
##
## $ジェンツー
## # A tibble: 124 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Gentoo ジェンツー Biscoe 46.1 13.2 211 4500 fema…
## 2 Gentoo ジェンツー Biscoe 50 16.3 230 5700 male
## 3 Gentoo ジェンツー Biscoe 48.7 14.1 210 4450 fema…
## # … with 121 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
##
## $ヒゲ
## # A tibble: 68 × 9
## species 種類 island bill_len…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Chinstrap ヒゲ Dream 46.5 17.9 192 3500 fema…
## 2 Chinstrap ヒゲ Dream 50 19.5 196 3900 male
## 3 Chinstrap ヒゲ Dream 51.3 19.2 193 3650 male
## # … with 65 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
それぞれのExcelシートから読みこまれた3つのデータ(アデリー、ジェンツー、ヒゲ)はデータフレームとして、df_list
にリストと呼ばれる形式にてまとめて格納されています。リストは最初は理解が難しいですが、慣れるとなんでもリストにしたくなるくらい便利なものです。リストの中身を個別に取り出してみてみましょう。
df_list$ジェンツー
## # A tibble: 124 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Gentoo ジェンツー Biscoe 46.1 13.2 211 4500 fema…
## 2 Gentoo ジェンツー Biscoe 50 16.3 230 5700 male
## 3 Gentoo ジェンツー Biscoe 48.7 14.1 210 4450 fema…
## # … with 121 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
これは、df_list
というリストの中の、ジェンツー
という要素(ここではデータフレーム)を取り出す、というコードです。$
が「(左側にくるオブジェクト)の中の」という意味を表しています。自分でコードを打つと、df_list$
と打った時点で、中の要素の一覧が表示されるはずなので、そこからクリックして選ぶこともできます。
それでは、先ほど実行した読み込みコードの解説をします。
path_name <- "data/ペンギン(シート別).xlsx"
これは、単にファイルの場所をpath_name
に格納しただけです。自分のデータで試してみたいときは、基本的にここのパス名を変えるだけで実行できるはずです。
df_list <-
excel_sheets(path_name) |>
set_names() |>
map(read_excel, path = path_name)
excel_sheets()
は上で実行したのと同じです。実行結果はベクトルとして保存されています。set_names()
は、ベクトルを名前付きベクトルにする働きをします。なので、ここでできるのは、
excel_sheets(path_name) |>
set_names()
## アデリー ジェンツー ヒゲ
## "アデリー" "ジェンツー" "ヒゲ"
です。
それぞれについてpurrr
パッケージのmap()
関数を使ってread_excel()
を1つ1つのシート(ここでは作成した名前付きベクトルの要素)に適用していき、データを読み込みデータフレームにし、1つのリストにまとめるという作業をします。繰り返し似たような作業をするときに、このmap()
関数が非常に便利です。
2.2.4.1 一つのデータフレームにする
bind_rows()
は、データフレームを縦に連結します。データフレームがリストになったものが引数にくると、それらをすべて縦につなげてくれます。引数.id =
で、リストの要素名を変数の値として入れることができるので、どのデータフレームから来たのか識別することが可能になります。ここではgroup
という名前にしています。
df_all <-
bind_rows(df_list, .id = "group")
2.2.4.2 作成したデータフレームの確認
最初の3行と最後の3行だけを表示してどんなものができたか確認します。dplyr
パッケージのslice_head()
, slice_tail()
関数を使って、引数n =
に表示したい行数を指定することで、最初および最後の数行を取得できます。
# 最初の3行
df_all |> slice_head(n = 3)
## # A tibble: 3 × 10
## group species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 アデリー Adelie アデリ… Torge… 39.1 18.7 181 3750
## 2 アデリー Adelie アデリ… Torge… 39.5 17.4 186 3800
## 3 アデリー Adelie アデリ… Torge… 40.3 18 195 3250
## # … with 2 more variables: sex <chr>, year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
# 最後の3行
df_all |> slice_tail(n = 3)
## # A tibble: 3 × 10
## group species 種類 island bill_len…¹ bill_…² flipp…³ body_…⁴
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 ヒゲ Chinstrap ヒゲ Dream 49.6 18.2 193 3775
## 2 ヒゲ Chinstrap ヒゲ Dream 50.8 19 210 4100
## 3 ヒゲ Chinstrap ヒゲ Dream 50.2 18.7 198 3775
## # … with 2 more variables: sex <chr>, year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
一気にやるにはslice()
関数が便利です。1:3
は1行目から3行目、(n()-2):n()
は、列数(ただし現在のgroup内)を表すn()
とそれから-2行した(n()-2)
で表されています。
## # A tibble: 6 × 10
## group species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴
## <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 アデリー Adelie アデ… Torge… 39.1 18.7 181 3750
## 2 アデリー Adelie アデ… Torge… 39.5 17.4 186 3800
## 3 アデリー Adelie アデ… Torge… 40.3 18 195 3250
## 4 ヒゲ Chinstrap ヒゲ Dream 49.6 18.2 193 3775
## 5 ヒゲ Chinstrap ヒゲ Dream 50.8 19 210 4100
## 6 ヒゲ Chinstrap ヒゲ Dream 50.2 18.7 198 3775
## # … with 2 more variables: sex <chr>, year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
2.3 複数のExcelファイルを読み込む
それでは、さらにRの恩恵を深く実感できる部分に入ります。読みこみたいExcelファイルが大量にある場合です。これも実務上よく遭遇します。やり方としては、2.2.4で使った方法とほぼ同じです。
ただし、ここでは読み込むファイルの構造がすべて同様の場合に限ります。残念ながら、それがかなわない状況に、現実ではたくさん遭遇します。いつか本書の応用編を書くことがあったら、そちらで解説することとして、今回は構造が単純な場合に限って解説します。
おそらく、単純に思いつく方法は、
df_Adelie <- read_xlsx("data/複数/アデリー.xlsx")
df_Gentoo <- read_xlsx("data/複数/ジェンツー.xlsx")
df_Chinstrap <- read_xlsx("data/複数/ヒゲ.xlsx")
と1つずつ読んでいく方法ですが、これも大量にあったら泣きたくなる作業です。1つ1つファイル名を入力やコピペする間にいくらでもミスが生じます。2.1.1.1で紹介した自動補完を使っても、楽しいのは最初だけでしょう。そこで、ファイルを指定するところから極力人の手を介さず進めていく方法を次に解説していきます。
2.3.1 読み込むファイル名の一覧のオブジェクト作成
まず、読み込みたいファイルが格納されているフォルダのファイル名、およびパス名の一覧を取得します。
files <-
list.files(path = "data/複数/", full.names = TRUE)
files
## [1] "data/複数/Adelie.csv" "data/複数/Chinstrap.csv"
## [3] "data/複数/Gentoo.csv" "data/複数/アデリー.xlsx"
## [5] "data/複数/ジェンツー.xlsx" "data/複数/ヒゲ.xlsx"
## [7] "data/複数/フォルダ1" "data/複数/フォルダ2"
## [9] "data/複数/フォルダ3"
list.files()
関数は、path =
で指定したフォルダ内の情報を取得します。full.names = TRUE
でパスも含めます。これをつけないと、ファイル名と拡張子だけの取得になります。
このうち、使用するのはxlsxファイルだけなので、文字列で該当するデータを取得するstr_subset()
を用い、以下のように限定します。
files <-
files |> str_subset("xlsx")
files
## [1] "data/複数/アデリー.xlsx" "data/複数/ジェンツー.xlsx"
## [3] "data/複数/ヒゲ.xlsx"
2.3.2 ファイルを一括で読み込む
## [[1]]
## # A tibble: 152 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデリー Torgers… 39.1 18.7 181 3750 male
## 2 Adelie アデリー Torgers… 39.5 17.4 186 3800 fema…
## 3 Adelie アデリー Torgers… 40.3 18 195 3250 fema…
## # … with 149 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
##
## [[2]]
## # A tibble: 124 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Gentoo ジェンツー Biscoe 46.1 13.2 211 4500 fema…
## 2 Gentoo ジェンツー Biscoe 50 16.3 230 5700 male
## 3 Gentoo ジェンツー Biscoe 48.7 14.1 210 4450 fema…
## # … with 121 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
##
## [[3]]
## # A tibble: 68 × 9
## species 種類 island bill_len…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Chinstrap ヒゲ Dream 46.5 17.9 192 3500 fema…
## 2 Chinstrap ヒゲ Dream 50 19.5 196 3900 male
## 3 Chinstrap ヒゲ Dream 51.3 19.2 193 3650 male
## # … with 65 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
ここでできたldata
は、2.2.4で作成したdf_list
と同じ構造です。違いはそれぞれのデータフレームの要素名(アデリー、ジェンツー、ヒゲ)が入っていない点です。各要素の上の部分にある名前が[[1]], [[2]], [[3]]
と表示されています(つまり、1, 2, 3の数値が割り当てられている)。要素名が入っていないのは不便なので、以下で要素名を改めてつけます。
2.3.2.1 ファイル名抽出
先ほど作成したfiles
から、ファイル名部分だけに加工します。str_replace()
は、stringr
パッケージの、文字の置換をする関数です。ここでは、拡張子とパス名をそれぞれ""
、つまり空白に置換しています。
file_name <-
str_replace(files, ".xlsx", "") |>
str_replace("data/複数/", "")
file_name
## [1] "アデリー" "ジェンツー" "ヒゲ"
2.3.2.2 リストの要素名にファイル名を付与
2.2.4で使ったset_names()
関数は、リストの要素名を付ける時にも使えます。リストldata
の3つの要素に、file_name
の中身を割り当てます。
ldata <-
set_names(ldata, file_name)
ldata
## $アデリー
## # A tibble: 152 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Adelie アデリー Torgers… 39.1 18.7 181 3750 male
## 2 Adelie アデリー Torgers… 39.5 17.4 186 3800 fema…
## 3 Adelie アデリー Torgers… 40.3 18 195 3250 fema…
## # … with 149 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
##
## $ジェンツー
## # A tibble: 124 × 9
## species 種類 island bill_…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Gentoo ジェンツー Biscoe 46.1 13.2 211 4500 fema…
## 2 Gentoo ジェンツー Biscoe 50 16.3 230 5700 male
## 3 Gentoo ジェンツー Biscoe 48.7 14.1 210 4450 fema…
## # … with 121 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
##
## $ヒゲ
## # A tibble: 68 × 9
## species 種類 island bill_len…¹ bill_…² flipp…³ body_…⁴ sex
## <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 Chinstrap ヒゲ Dream 46.5 17.9 192 3500 fema…
## 2 Chinstrap ヒゲ Dream 50 19.5 196 3900 male
## 3 Chinstrap ヒゲ Dream 51.3 19.2 193 3650 male
## # … with 65 more rows, 1 more variable: year <dbl>, and
## # abbreviated variable names ¹bill_length_mm, ²bill_depth_mm,
## # ³flipper_length_mm, ⁴body_mass_g
このように、ちゃんと要素に名前が付きました。これらを1つのデータフレームにまとめるには、 2.2.4.1と同じ手順でできます。
bind_rows(ldata, .id = "group")
2.3.3 読み込むファイルが複数フォルダにある場合
data/複数
フォルダの中に、さらにフォルダ1~フォルダ3がありました。この中にもそれぞれxlsxファイルが入っていて、それぞれ読み込みたいとします。その場合は、先ほど使ったlist.files()
関数の引数、recursive = TRUE
を追加します。これによって、フォルダの深い階層までもすべて読み込むことが可能になります。
files <-
list.files(path = "data/複数/", full.names = TRUE, recursive = TRUE)
files
## [1] "data/複数//フォルダ1/アデリー.xlsx"
## [2] "data/複数//フォルダ2/ジェンツー.xlsx"
## [3] "data/複数//フォルダ3/ヒゲ.xlsx"
## [4] "data/複数/Adelie.csv"
## [5] "data/複数/Chinstrap.csv"
## [6] "data/複数/Gentoo.csv"
## [7] "data/複数/アデリー.xlsx"
## [8] "data/複数/ジェンツー.xlsx"
## [9] "data/複数/ヒゲ.xlsx"
このうち、使用するのはフォルダ1~3に入っているxlsxファイルだけなので、str_subset()
関数で以下のように絞り込みます。ここの""
の中に入る文字列がどうなるかが難しいところかもしれませんが、ここは正規表現という本書の範囲を超える世界なので、深入りはしません。
files <-
files |> str_subset("フォルダ")
あとは2.3.2と同じ手順で読み込めます。