tidyverse パッケージは、readr パッケージ、dplyr パッケージ、ggplot2 パッケージ、tidyr パッケージなどのデータの操作および視覚化用のパッケージをまとめたパッケージである。tidyverse を利用ことで、データの操作や視覚化が容易になるだけでなく、コーディング量が減り、コーディングミスによる間違いなども起こしにくく、解析作業が効率的になる。
tidyverse パッケージは CRAN のパッケージとして提供されている。CRAN のパッケージをインストールするとき、install.packages
関数する。tidyverse パッケージをインストールすることで、readr パッケージ、dplyr パッケージ、ggplot2 パッケージ、tidyr パッケージなどを自動的にインストールされる。
install.packages('tidyverse')
tidyverse パッケージを呼び出すときは、R の他のパッケージと同様に library
関数を使う。tidyverse パッケージを呼び出すだけで、自動的に dplyr や ggplot2 などのパッケージも呼び出され、使えるようになる。
library(tidyverse)
## ── Attaching packages ────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.2.1 ✔ purrr 0.3.2
## ✔ tibble 2.1.3 ✔ dplyr 0.8.3
## ✔ tidyr 0.8.3 ✔ stringr 1.4.0
## ✔ readr 1.3.1 ✔ forcats 0.4.0
## ── Conflicts ───────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
readr パッケージは、ファイルからデータを読み込んだり、データをファイルに書き出したり、文字列をパースしたりする際に利用する関数をまとめたパッケージである。これらの関数は R に標準実装されているが、readr の関数を使用した方が、R の標準関数に比べて速度が速く、効率的な処理を行える。
readr パッケージでは、ファイルからデータを読み込むときに使用する関数として read_csv
や read_tsv
などが用意されている。これらの関数は R の標準関数である read.csv
や read.table
関数とほぼ同じ機能を持つが、次のような点で異なっている。
read_csv
や read_tsv
関数にはお節介な機能がない。
CSV ファイルの読み込みは read_csv
関数を使用する。
d <- read_csv('data/rice.csv')
head(d)
TSV ファイルの読み込みは read_tsv
関数を使用する。
d <- read_tsv('data/rice.txt')
head(d)
区切り文字を指定して、ファイルからデータを読み込むときに read_delim
関数を使用する。このとき、区切り文字を delim
オプションで指定する。
d <- read_delim('data/rice.txt', delim = '\t')
head(d)
ファイル書き出し用の関数には write_csv
、write_tsv
、write_delim
などの関数が用意されている。これら関数を使用して、データをファイルに保存する際に、文字コードが UTF-8 として保存される。使い方は R の標準関数とほぼ同じように使う。
write_csv(d, 'data/results.csv')
write_tsv(d, 'data/results.csv')
write_tsv(d, 'data/results.csv', delim = ';')
readr パッケージには文字列をパースするための関数が用意されている。
関数 | 機能 |
---|---|
parse_logical | 文字列を理論型(TRUE または FALSE )に変換する。 |
parse_integer | 文字列を整数型に変換する。 |
parse_double | 文字列を小数型に変換する。 |
parse_character | 文字列を文字型に変換する。UTF-8 以外の文字列コードから UTF-8 に変換するときに使用する。 |
parse_datetime | 文字列を datetime 型に変換する。 |
parse_date | 文字列を date 型に変換する。 |
parse_time | 文字列を time 型に変換する。 |
parse_number | 文字列中に含まれている数字を整数に変換する。 |
x <- c('TRUE', 'FALSE')
y <- parse_logical(x)
print(y)
## [1] TRUE FALSE
x <- c('64')
y <- parse_integer(x)
print(y)
## [1] 64
x <- c('3.14')
y <- parse_integer(x)
## Warning: 1 parsing failure.
## row col expected actual
## 1 -- no trailing characters .14
print(y)
## [1] NA
## attr(,"problems")
## # A tibble: 1 x 4
## row col expected actual
## <int> <int> <chr> <chr>
## 1 1 NA no trailing characters .14
x <- c('3.14')
y <- parse_double(x)
print(y)
## [1] 3.14
x <- "\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd"
y <- parse_character(x, locale = locale(encoding = "Shift-JIS"))
print(y)
## [1] "こんにちは"
x <- "2019-10-20 10:00:00"
y <- parse_datetime(x)
print(y)
## [1] "2019-10-20 10:00:00 UTC"
x <- "2019-10-20"
y <- parse_date(x)
print(y)
## [1] "2019-10-20"
x <- "23:00:00"
y <- parse_time(x)
print(y)
## 23:00:00
x <- "11:00:00 pm"
y <- parse_time(x)
print(y)
## 23:00:00
print(parse_number("123,456,789")) # US, JP, ...
## [1] 123456789
print(parse_number("123.456.789", locale = locale(grouping_mark = "."))) # EU
## [1] 123456789
print(parse_number("123'456'789", locale = locale(grouping_mark = "'"))) # CH
## [1] 123456789
dplyr は表型データの操作に特化した R のパッケージである。dplyr パッケージには、表型データの中からサブセットを抽出したりする関数や抽出したサブセットに対して集計を行う関数などが多数用意されている。dplyr で扱うデータは数百 MB から 2 GB 前後のサイズを想定している。このサイズを超えるような 10〜100 GB 規模なビッグデータなどを取り扱う場合は、 data.table パッケージを使用した方が無難。
dplyr の関数の記述方法が非常にシンプルであり、可読性が良い。dplyr を使用することで、研究者はデータの操作や集計に集中することができ、集計等に関係しない無駄なコードを書かなくて済む。
R では、データフレームの中からある条件を満たすサブセットを抽出し、そのサブセットの平均値を求めたりすることが簡単にできる。ここで、 rice.txt データセットを使って、データの操作方法を示す。rice データセットは 7 列を持ち、それぞれの列が個体番号(replicate)、ブロック番号(block)、根部乾燥重量(root_dry_mass)、地上部乾燥重量(shoot_dry_mass)、系統処理(trt)、処理(fert)、系統(variety)からなる。
d <- read.table('data/rice.txt', header = TRUE, sep = '\t')
head(d)
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## 1 1 1 56 132 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 3 1 40 108 F10 F10 wt
## 4 4 1 43 134 F10 F10 wt
## 5 5 1 55 119 F10 F10 wt
## 6 6 1 66 125 F10 F10 wt
ここで、例えば、各系統(wt 系統および ANU843 系統)に対して、根部乾燥重量を求める場合は、データフレームに対して、次のようの操作を行うことで計算できる。
wt <- d$root_dry_mass[d$variety == 'wt']
ANU843 <- d$root_dry_mass[d$variety == 'ANU843']
print(mean(wt))
## [1] 26.47222
print(mean(ANU843))
## [1] 9.666667
平均値・最大値・最小値などの簡単な値を求めるとき、R の標準関数の一つである aggregate
関数を使うと便利である。
aggregate(d$root_dry_mass, by = list(variety = d$variety), mean)
## variety x
## 1 ANU843 9.666667
## 2 wt 26.472222
wt 系統および ANU843 系統の中に、F10 処理、NH4Cl 処理、NH4NO3 処理の 3 つの処理群が含まれている。ここで、wt 系統と ANU843 系統の各処理群それぞれに対して、根部乾燥重量の平均を計算してみる。
wt.F10 <- d$root_dry_mass[d$variety == 'wt' & d$fert == 'F10']
wt.NH4Cl <- d$root_dry_mass[d$variety == 'wt' & d$fert == 'NH4Cl']
wt.NH4NO3 <- d$root_dry_mass[d$variety == 'wt' & d$fert == 'NH4NO3']
ANU843.F10 <- d$root_dry_mass[d$variety == 'ANU843' & d$fert == 'F10']
ANU843.NH4Cl <- d$root_dry_mass[d$variety == 'ANU843' & d$fert == 'NH4Cl']
ANU843.NH4NO3 <- d$root_dry_mass[d$variety == 'ANU843' & d$fert == 'NH4NO3']
m <- c(mean(wt.F10), mean(wt.NH4Cl), mean(wt.NH4NO3),
mean(ANU843.F10), mean(ANU843.NH4Cl), mean(ANU843.NH4NO3))
print(m)
## [1] 49.500000 12.583333 17.333333 6.000000 9.166667 13.833333
複数条件の組み合わせでも aggregate
関数が使える。例えば次のように by
オプションに、2 つの条件を与えればよい。
aggregate(d$root_dry_mass, by = list(variety = d$variety, fert = d$fert), mean)
## variety fert x
## 1 ANU843 F10 6.000000
## 2 wt F10 49.500000
## 3 ANU843 NH4Cl 9.166667
## 4 wt NH4Cl 12.583333
## 5 ANU843 NH4NO3 13.833333
## 6 wt NH4NO3 17.333333
dplyr を使用してデータ操作を扱うとき、データの流れに着目するとわかりやすい。例えば、d
というデータに対して A
処理を行なった後に、B
処理を行い、その結果を x
に保存したい場合は、d
→ A
→ B
→ x
という流れに着目すると、dplyr のルールに従うと次のように記述することができる。d
の内容を関数 A
に流すときに %>%
演算子を使用する。次に、A
関数で処理した結果を B
関数に流すときに同様に %>%
演算子を使用する。最後に、関数 B
の処理結果を x
に代入したいから、R の基本文法により <-
を使用する。
x <- d %>% A %>% B
dplyr の記述ルールを踏まえて、wt 系統の個体数を求めるには、次のように行う。データ d
を group_by
関数に流し、ここで variety
ごとにグループ分けを行う。グループ分けを行なった後に、各グループをさらに次の summarise
関数に流し、平均を求める処理を行なっている。
d <- read_tsv('data/rice.txt')
## Parsed with column specification:
## cols(
## replicate = col_double(),
## block = col_double(),
## root_dry_mass = col_double(),
## shoot_dry_mass = col_double(),
## trt = col_character(),
## fert = col_character(),
## variety = col_character()
## )
head(d)
## # A tibble: 6 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 1 1 56 132 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 3 1 40 108 F10 F10 wt
## 4 4 1 43 134 F10 F10 wt
## 5 5 1 55 119 F10 F10 wt
## 6 6 1 66 125 F10 F10 wt
variety_ave <- d %>%
group_by(variety) %>%
summarise(mass_ave = mean(root_dry_mass))
head(variety_ave)
## # A tibble: 2 x 2
## variety mass_ave
## <chr> <dbl>
## 1 ANU843 9.67
## 2 wt 26.5
各系統の各処理群に対して平均を求める場合は、aggregate
関数と同様に、group_by
のところに条件を 2 つ書けばよい。
variety_ave <- d %>%
group_by(variety, fert) %>%
summarise(mass_ave = mean(root_dry_mass))
head(variety_ave)
## # A tibble: 6 x 3
## # Groups: variety [2]
## variety fert mass_ave
## <chr> <chr> <dbl>
## 1 ANU843 F10 6
## 2 ANU843 NH4Cl 9.17
## 3 ANU843 NH4NO3 13.8
## 4 wt F10 49.5
## 5 wt NH4Cl 12.6
## 6 wt NH4NO3 17.3
このように、dplyr ではデータの流れに着目して、データの操作や集計を行なっていくことができる。研究者がデータ操作・データ集計に関係のないコードを書く必要がなく、効率的である。
dplyr パッケージの中で、表データ操作の目的でよく使われる関数として、次のような関数がある。
関数 | 動作 |
---|---|
select | 与えられた条件に基づいて、特定の列を抽出する。 |
filter | 与えられた条件に基づいて、特定の行を抽出する。 |
arrange | 与えられた条件に基づいて、行を並べ替える。 |
group_by | 与えられた条件に基づいて、データセット全体をいくつかのグループに分ける。 |
summarise | 最大値・最小値・平均値を求めるなどのデータの集計を行う。 |
mutate | 既存のデータセットに新しい列を加える。 |
また、 2 つの表データを結合したりする関数も用意されている。
関数 | 動作 |
---|---|
inner_join | 2 つの表データを内部結合させる。 |
left_join | 2 つの表データを左外部結合させる。 |
right_join | 2 つの表データを右外部結合させる。 |
full_join | 2 つの表データを完全外部結合させる。 |
select
関数は、与えられた条件に基づいて、特定の列を抽出する関数である。例えば rice データセットから、系統(variety)、処理(fert)、根部乾燥重量(root_dry_mass)、地上部乾燥重量(shoot_dry_mass)の 4 列だけを取り出してサブセットを作成したい場合は、次のようにする。
# d.subset <- d[, c('variety', 'fert', 'root_dry_mass', 'shoot_dry_mass')]
d.subset <- d %>% select(variety, fert, root_dry_mass, shoot_dry_mass)
head(d.subset)
## # A tibble: 6 x 4
## variety fert root_dry_mass shoot_dry_mass
## <chr> <chr> <dbl> <dbl>
## 1 wt F10 56 132
## 2 wt F10 66 120
## 3 wt F10 40 108
## 4 wt F10 43 134
## 5 wt F10 55 119
## 6 wt F10 66 125
select
関数に列名を指定するとき、-
をつけると、その列を含まないようなサブセットが作成される。
# d.subset <- d[, -c('replicate', 'block', 'trt')]
d.subset <- d %>% select(-replicate, -block, -trt)
head(d.subset)
## # A tibble: 6 x 4
## root_dry_mass shoot_dry_mass fert variety
## <dbl> <dbl> <chr> <chr>
## 1 56 132 F10 wt
## 2 66 120 F10 wt
## 3 40 108 F10 wt
## 4 43 134 F10 wt
## 5 55 119 F10 wt
## 6 66 125 F10 wt
select
関数に列名ではなく、条件を与えて列名を列を抽出することもできる。例えば、列名に mass
を含む列を抽出する場合は次のようにする。
d.subset <- d %>% select(contains('mass'))
head(d.subset)
## # A tibble: 6 x 2
## root_dry_mass shoot_dry_mass
## <dbl> <dbl>
## 1 56 132
## 2 66 120
## 3 40 108
## 4 43 134
## 5 55 119
## 6 66 125
抽出条件を与えるときに使用した contains
関数の他に、starts_with
、ends_with
、matches
などの関数も使用できる。
filter
関数は与えられた条件に基づいて、特定の行を抽出する関数である。例えば、根部乾燥重量が 50 以上の行を抽出するには、次のように行う。
d.subset <- d %>% filter(root_dry_mass > 50)
head(d.subset)
## # A tibble: 5 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 1 1 56 132 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 5 1 55 119 F10 F10 wt
## 4 6 1 66 125 F10 F10 wt
## 5 8 2 67 122 F10 F10 wt
条件が複数ある場合は、それらの条件を順に filter
関数に加えればよい。例えば、wt 系統かつ根部乾燥重量が 50 以上の行を抽出するには、次のようにする。
d.subset <- d %>% filter(root_dry_mass >= 50, variety == 'wt')
head(d.subset)
## # A tibble: 5 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 1 1 56 132 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 5 1 55 119 F10 F10 wt
## 4 6 1 66 125 F10 F10 wt
## 5 8 2 67 122 F10 F10 wt
複数条件の場合は &
および |
を使って AND 演算および OR 演算を行うことができる。例えば、「wt 系統」、「根部乾燥重量が 50 以上」、「地上部乾燥重量が 120 以上」の 3 つの条件を同時に満たす行を抽出する場合は、次のようにする。 ただし、複数の条件をカンマで区切って与える場合は AND 演算の結果が行われる。
d.subset <- d %>% filter(variety == 'wt', root_dry_mass >= 50, shoot_dry_mass >= 120)
# d.subset <- d %>% filter(variety == 'wt' & root_dry_mass >= 50 & shoot_dry_mass >= 120)
head(d.subset)
## # A tibble: 4 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 1 1 56 132 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 6 1 66 125 F10 F10 wt
## 4 8 2 67 122 F10 F10 wt
wt 系統で、「根部乾燥重量が 50 以上」または「地上部乾燥重量が 120 以上」の条件を満たす行を抽出する場合は、次のようにする。
d.subset <- d %>% filter(variety == 'wt', root_dry_mass >= 50 | shoot_dry_mass >= 120)
# d.subset <- d %>% filter(variety == 'wt' & (root_dry_mass >= 50 | shoot_dry_mass >= 120))
head(d.subset)
## # A tibble: 6 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 1 1 56 132 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 4 1 43 134 F10 F10 wt
## 4 5 1 55 119 F10 F10 wt
## 5 6 1 66 125 F10 F10 wt
## 6 8 2 67 122 F10 F10 wt
別の例として、処理群が F10 以外の行を抽出するときは次のように !
を使う。
# d.subset <- d %>% filter(!(fert == 'F10'))
d.subset <- d %>% filter(fert != 'F10')
head(d.subset)
## # A tibble: 6 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 1 1 12 45 NH4Cl NH4Cl wt
## 2 2 1 20 60 NH4Cl NH4Cl wt
## 3 3 1 21 87 NH4Cl NH4Cl wt
## 4 4 1 15 57 NH4Cl NH4Cl wt
## 5 5 1 5 26 NH4Cl NH4Cl wt
## 6 6 1 18 78 NH4Cl NH4Cl wt
arrange
関数は、与えられた条件に基づいて、行を並べ替える。データに欠損値 NA
が含まれる場合は、arrange
関数を使って並べ替えるとき、昇順・降順に関わらず、欠損値 NA
は常にデータセットの最下部に並べ替えられる。例えば、rice データに対して、根部乾燥重量に基づいて昇順に並べ替えたい場合は、arrange
関数に列名 root_dry_mass
を指定すればよい。
d.subset <- d %>% arrange(root_dry_mass)
head(d.subset)
## # A tibble: 6 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 7 2 1 35 NH4Cl +ANU843 NH4Cl ANU843
## 2 10 2 3 5 F10 +ANU843 F10 ANU843
## 3 2 1 4 6 F10 +ANU843 F10 ANU843
## 4 3 1 4 3 F10 +ANU843 F10 ANU843
## 5 1 1 4 22 NH4Cl +ANU843 NH4Cl ANU843
## 6 5 1 5 26 NH4Cl NH4Cl wt
根部乾燥重量に基づいて降順に並べ替えたい場合は、desc
関数を利用するか、列名に -
をつけるかで並べ替えられる。
# d.subset <- d %>% arrange(-root_dry_mass)
d.subset <- d %>% arrange(desc(root_dry_mass))
head(d.subset)
## # A tibble: 6 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 8 2 67 122 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 6 1 66 125 F10 F10 wt
## 4 1 1 56 132 F10 F10 wt
## 5 5 1 55 119 F10 F10 wt
## 6 11 2 44 37 F10 F10 wt
次に、根部乾燥重量に関して降順で、地上部乾燥重量に関しては昇順で並べるときは、filter
関数と同様に複数の条件を順に与えればよい。filter
関数に複数の条件を代入した場合は、左側の条件が優先される。
d.subset <- d %>% arrange(desc(root_dry_mass), shoot_dry_mass)
head(d.subset)
## # A tibble: 6 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 8 2 67 122 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 6 1 66 125 F10 F10 wt
## 4 1 1 56 132 F10 F10 wt
## 5 5 1 55 119 F10 F10 wt
## 6 11 2 44 37 F10 F10 wt
これまでに紹介した select
関数、filter
関数および arrange
関数を組み合わせることで、データセットを柔軟に操作できる。例えば、次のような操作も簡単に行える。
wt.subset <- d %>%
filter(variety == 'wt') %>%
select(fert, root_dry_mass, shoot_dry_mass) %>%
arrange(desc(root_dry_mass))
head(wt.subset)
## # A tibble: 6 x 3
## fert root_dry_mass shoot_dry_mass
## <chr> <dbl> <dbl>
## 1 F10 67 122
## 2 F10 66 120
## 3 F10 66 125
## 4 F10 56 132
## 5 F10 55 119
## 6 F10 44 37
group_by
関数は、与えられた条件い基づいて、データをいくつかのグループ分けるときに使用する関数である。group_by
関数で処理した結果を print
しても、group_by
関数の処理前と処理後とでは見た目的には変わらない。しかし、group_by
関数で処理した後のデータセットには、グループ情報が属性として保存される。例えば、rice データセットに対して、各系統ごとにグループ分けを行う場合は次のようにする。
head(d)
## # A tibble: 6 x 7
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 1 1 56 132 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 3 1 40 108 F10 F10 wt
## 4 4 1 43 134 F10 F10 wt
## 5 5 1 55 119 F10 F10 wt
## 6 6 1 66 125 F10 F10 wt
d.grouped <- d %>% group_by(variety)
head(d.grouped)
## # A tibble: 6 x 7
## # Groups: variety [1]
## replicate block root_dry_mass shoot_dry_mass trt fert variety
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr>
## 1 1 1 56 132 F10 F10 wt
## 2 2 1 66 120 F10 F10 wt
## 3 3 1 40 108 F10 F10 wt
## 4 4 1 43 134 F10 F10 wt
## 5 5 1 55 119 F10 F10 wt
## 6 6 1 66 125 F10 F10 wt
group_by
関数で追加されたグループ情報を削除したい場合は ungroup
関数を使用する。
d.grouped <- d %>% group_by(variety)
d.ungrouped <- d.grouped %>% ungroup()
summarise
関数はデータの集計を行う関数で、group_by
関数などと一緒に使われることが多い。例えば、rice データセットに対して、各系統ごとに根部乾燥重量および地上部乾燥重量の平均値を求めたい場合は、まず variety 列に基づいてグループ分けを行い、続いて根部乾燥重量および地上部乾燥重量の列に対して集計処理(平均値計算)を行う。
d.massave <- d %>%
group_by(variety) %>%
summarise(root_dry_mass_ave = mean(root_dry_mass),
shoot_dry_mass_ave = mean(shoot_dry_mass))
head(d.massave)
## # A tibble: 2 x 3
## variety root_dry_mass_ave shoot_dry_mass_ave
## <chr> <dbl> <dbl>
## 1 ANU843 9.67 41.8
## 2 wt 26.5 77.3
各系統の各処理群に対して平均を求める場合は、group_by
のところに条件を 2 つ書く。
d.massave <- d %>%
group_by(variety, fert) %>%
summarise(root_dry_mass_ave = mean(root_dry_mass),
shoot_dry_mass_ave = mean(shoot_dry_mass))
head(d.massave)
## # A tibble: 6 x 4
## # Groups: variety [2]
## variety fert root_dry_mass_ave shoot_dry_mass_ave
## <chr> <chr> <dbl> <dbl>
## 1 ANU843 F10 6 7.33
## 2 ANU843 NH4Cl 9.17 46.6
## 3 ANU843 NH4NO3 13.8 71.5
## 4 wt F10 49.5 108.
## 5 wt NH4Cl 12.6 50.2
## 6 wt NH4NO3 17.3 73.3
summarise
の中で使われている mean
関数は R の標準関数である。そのため、欠損地を無視して平均値を求めたい場合は、次のように書けばよい。
d.massave <- d %>%
group_by(variety, fert) %>%
summarise(root_dry_mass_ave = mean(root_dry_mass, na.rm = TRUE),
shoot_dry_mass_ave = mean(shoot_dry_mass, na.rm = TRUE))
head(d.massave)
## # A tibble: 6 x 4
## # Groups: variety [2]
## variety fert root_dry_mass_ave shoot_dry_mass_ave
## <chr> <chr> <dbl> <dbl>
## 1 ANU843 F10 6 7.33
## 2 ANU843 NH4Cl 9.17 46.6
## 3 ANU843 NH4NO3 13.8 71.5
## 4 wt F10 49.5 108.
## 5 wt NH4Cl 12.6 50.2
## 6 wt NH4NO3 17.3 73.3
summarise
中で使用する関数を独自に定義することもできる。例えば、四分位範囲(IQR)を求める関数 calc.IQR
を独自に定義して、それを summarise
中で使う場合は次のようにする。
calc.IQR <- function(x) {
q1 <- quantile(x, probs = 0.25)
q3 <- quantile(x, probs = 0.75)
iqr <- q3 - q1
return(iqr)
}
d.massave <- d %>%
group_by(variety, fert) %>%
summarise(root_dry_mass_IQR = calc.IQR(root_dry_mass),
shoot_dry_mass_IQR = calc.IQR(shoot_dry_mass))
head(d.massave)
## # A tibble: 6 x 4
## # Groups: variety [2]
## variety fert root_dry_mass_IQR shoot_dry_mass_IQR
## <chr> <chr> <dbl> <dbl>
## 1 ANU843 F10 2.25 4
## 2 ANU843 NH4Cl 2.5 23.2
## 3 ANU843 NH4NO3 8 25.8
## 4 wt F10 17.8 17.2
## 5 wt NH4Cl 11 19.2
## 6 wt NH4NO3 8 24
mutate
関数は、既存のデータに新しい列を加えたいときに使用する。例えば、根部乾燥重量と地上部乾燥重量の和を計算して、それを dry_mass 列名で既存のデータに追加し、さらに根部乾燥重量が乾燥重量全体における割合を root_dry_mass_ratio 列名で既存のデータに追加する場合は、次のようにする。
d.new <- d %>% mutate(dry_mass = root_dry_mass + shoot_dry_mass,
root_dry_mass_ratio = root_dry_mass / dry_mass)
head(d.new)
## # A tibble: 6 x 9
## replicate block root_dry_mass shoot_dry_mass trt fert variety dry_mass
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <chr> <dbl>
## 1 1 1 56 132 F10 F10 wt 188
## 2 2 1 66 120 F10 F10 wt 186
## 3 3 1 40 108 F10 F10 wt 148
## 4 4 1 43 134 F10 F10 wt 177
## 5 5 1 55 119 F10 F10 wt 174
## 6 6 1 66 125 F10 F10 wt 191
## # … with 1 more variable: root_dry_mass_ratio <dbl>
新たに作成した列名だけを新しいデータとしたい場合は mutate
関数の代わりに transmute
関数を使う。この際、既存の列名を残すこともできる。
d.new <- d %>% transmute(variety,
dry_mass = root_dry_mass + shoot_dry_mass,
root_dry_mass_ratio = root_dry_mass / dry_mass)
head(d.new)
## # A tibble: 6 x 3
## variety dry_mass root_dry_mass_ratio
## <chr> <dbl> <dbl>
## 1 wt 188 0.298
## 2 wt 186 0.355
## 3 wt 148 0.270
## 4 wt 177 0.243
## 5 wt 174 0.316
## 6 wt 191 0.346
inner_join
関数は 2 つの表データを内部結合するための関数である。例えば、次のように d1
と d2
の表を用意し、d1
の fruit
列と d2
の fruit
列を参照列として、2 つの表を結合させる際に、次のようにする。ただし、内部結合では、両方の参照列に存在するキーのみに対して、結合が行われる。片方の参照列に存在し、もう片方に存在していないキーのデータは結合されない。
d1 <- dplyr::data_frame(fruit = c('apple', 'banana', 'cherry', 'orange'),
weight = c(42, 12, 3, 39))
## Warning: `data_frame()` is deprecated, use `tibble()`.
## This warning is displayed once per session.
d2 <- dplyr::data_frame(fruit = c('apple', 'banana', 'cherry', 'watermelon'),
volume = c(481, 436, 38, 3924))
d <- dplyr::inner_join(d1, d2, by = 'fruit')
d
## # A tibble: 3 x 3
## fruit weight volume
## <chr> <dbl> <dbl>
## 1 apple 42 481
## 2 banana 12 436
## 3 cherry 3 38
2 つの表データの参照列の名前が異なる時は、by
オプションで次のように指定する。
d1 <- dplyr::data_frame(fruit_x = c('apple', 'banana', 'cherry', 'orange'),
weight = c(42, 12, 3, 39))
d2 <- dplyr::data_frame(fruit_y = c('apple', 'banana', 'cherry', 'watermelon'),
volume = c(481, 436, 38, 3924))
d <- dplyr::inner_join(d1, d2, by = c('fruit_x' = 'fruit_y'))
d
## # A tibble: 3 x 3
## fruit_x weight volume
## <chr> <dbl> <dbl>
## 1 apple 42 481
## 2 banana 12 436
## 3 cherry 3 38
left_join
関数は 2 つの表データを左外部結合するための関数である。左外部結合では、2 つの表データを結合するとき、左側の表の参照列が基準となって結合が行われる。このため、左側の方の参照列に存在し、右側の方に存在していないキーのデータは、NA で補填される。
d1 <- dplyr::data_frame(fruit = c('apple', 'banana', 'cherry', 'orange'),
weight = c(42, 12, 3, 39))
d2 <- dplyr::data_frame(fruit = c('apple', 'banana', 'cherry', 'watermelon'),
volume = c(481, 436, 38, 3924))
d <- dplyr::left_join(d1, d2, by = 'fruit')
d
## # A tibble: 4 x 3
## fruit weight volume
## <chr> <dbl> <dbl>
## 1 apple 42 481
## 2 banana 12 436
## 3 cherry 3 38
## 4 orange 39 NA
right_join
関数は 2 つの表データを右外部結合するための関数である。右外部結合では、2 つの表データを結合するとき、右側の表の参照列が基準となって結合が行われる。このため、右側の方の参照列に存在し、左側の方に存在していないキーのデータは、NA で補填される。
d1 <- dplyr::data_frame(fruit = c('apple', 'banana', 'cherry', 'orange'),
weight = c(42, 12, 3, 39))
d2 <- dplyr::data_frame(fruit = c('apple', 'banana', 'cherry', 'watermelon'),
volume = c(481, 436, 38, 3924))
d <- dplyr::right_join(d1, d2, by = 'fruit')
d
## # A tibble: 4 x 3
## fruit weight volume
## <chr> <dbl> <dbl>
## 1 apple 42 481
## 2 banana 12 436
## 3 cherry 3 38
## 4 watermelon NA 3924
full_join
関数は 2 つの表データを外部結合するための関数である。片方の参照列に存在し、もう片方の参照列に存在してないようなキーのデータは NA
で補填される。
d1 <- dplyr::data_frame(fruit = c('apple', 'banana', 'cherry', 'orange'),
weight = c(42, 12, 3, 39))
d2 <- dplyr::data_frame(fruit = c('apple', 'banana', 'cherry', 'watermelon'),
volume = c(481, 436, 38, 3924))
d <- dplyr::full_join(d1, d2, by = 'fruit')
d
## # A tibble: 5 x 3
## fruit weight volume
## <chr> <dbl> <dbl>
## 1 apple 42 481
## 2 banana 12 436
## 3 cherry 3 38
## 4 orange 39 NA
## 5 watermelon NA 3924
tidyr はデータフレーム(正確には tibble 型のオブジェクト)の並べ方を展開したり、集約したりする際に利用する関数が多く用意されている。reshape2 パッケージの改良版という位置付けである。
tidyr パッケージの機能を説明するために、iris のデータセットを使用する。このデータセットは、次のように 150 行、5 列からなるデータフレームである。
iris <- read.table('data/iris.txt', header = TRUE, sep = '\t')
head(iris)
## ID Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 1 5.1 3.5 1.4 0.2 setosa
## 2 2 4.9 3.0 1.4 0.2 setosa
## 3 3 4.7 3.2 1.3 0.2 setosa
## 4 4 4.6 3.1 1.5 0.2 setosa
## 5 5 5.0 3.6 1.4 0.2 setosa
## 6 6 5.4 3.9 1.7 0.4 setosa
gather
関数はデータフレームにを折りたたむときに使う。例えば、雌しべおよび雄しべの長さと幅を attribute として、その値を value として折りたたむときは、次のように行う。
iris.df <- iris %>% gather(`Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`,
key = 'attribute', value = 'length')
head(iris.df)
## ID Species attribute length
## 1 1 setosa Sepal.Length 5.1
## 2 2 setosa Sepal.Length 4.9
## 3 3 setosa Sepal.Length 4.7
## 4 4 setosa Sepal.Length 4.6
## 5 5 setosa Sepal.Length 5.0
## 6 6 setosa Sepal.Length 5.4
折りたたまれたデータフレームを、特定の列に基づいて展開したいときは spread
関数を使用する。
iris.spreaded <- iris.df %>% spread(key = 'attribute', value = 'length')
head(iris.spreaded)
## ID Species Petal.Length Petal.Width Sepal.Length Sepal.Width
## 1 1 setosa 1.4 0.2 5.1 3.5
## 2 2 setosa 1.4 0.2 4.9 3.0
## 3 3 setosa 1.3 0.2 4.7 3.2
## 4 4 setosa 1.5 0.2 4.6 3.1
## 5 5 setosa 1.4 0.2 5.0 3.6
## 6 6 setosa 1.7 0.4 5.4 3.9
R の便利な機能を紹介している書籍が多数あり、それらが HTML としてウェブサイトで公開されている。tidyverse や ggplot2 についてもっと詳しく知りたい方、データ解析をもっと効率よく行いたい方は、ぜひ、次のウェブ資料を参考してみてください。