具体例_1
具体例_1: ほしいもの
このような結果がほしいとします:
## `summarise_each()` is deprecated.
## Use `summarise_all()`, `summarise_at()` or `summarise_if()` instead.
## To map `funs` over all variables, use `summarise_all()`
versicolor |
5.936 |
2.770 |
virginica |
6.588 |
2.974 |
setosa |
5.006 |
3.428 |
具体例_1: コード
iris %>%
dplyr::select(starts_with("sepal"),Species) %>%
dplyr::group_by(Species) %>%
dplyr::summarize_each(funs(mean)) %>%
dplyr::arrange(Sepal.Width)
## `summarise_each()` is deprecated.
## Use `summarise_all()`, `summarise_at()` or `summarise_if()` instead.
## To map `funs` over all variables, use `summarise_all()`
## # A tibble: 3 x 3
## Species Sepal.Length Sepal.Width
## <fctr> <dbl> <dbl>
## 1 versicolor 5.936 2.770
## 2 virginica 6.588 2.974
## 3 setosa 5.006 3.428
具体例_1: 内容
iris %>%
dplyr::select(starts_with("sepal"),Species) %>%
dplyr::group_by(Species) %>%
dplyr::summarize_each(funs(mean)) %>%
dplyr::arrange(Sepal.Width)
irisデータを…
"sepal"で始まる変数と"Species"を取り出して…
"Species"の値でグループ化して…
各列に対して"平均"で要約して…
"Sepal.Width"の昇順でソート
具体例_2
具体例_2: ほしいもの
このような結果がほしいとします:
Sepal.Length |
5.1 |
Sepal.Length |
4.9 |
Sepal.Length |
4.7 |
Sepal.Length |
4.6 |
Sepal.Length |
5.0 |
Sepal.Length |
5.4 |
具体例_2: コード
iris %>%
dplyr::select(-Species) %>%
tidyr::gather(key = var_name, value = value) %>%
head
## # A tibble: 6 x 2
## var_name value
## * <chr> <dbl>
## 1 Sepal.Length 5.1
## 2 Sepal.Length 4.9
## 3 Sepal.Length 4.7
## 4 Sepal.Length 4.6
## 5 Sepal.Length 5.0
## 6 Sepal.Length 5.4
具体例_2: 内容
iris %>%
dplyr::select(-Species) %>%
tidyr::gather(key = var_name, value = value) %>%
head
irisデータを…
"Species"以外の変数を取り出して…
4つの変数を縦型のデータに整形して…
上6つのデータを表示
補足: %>% について
%>% はpipe演算子
- “%>%”は、前のコマンドでのoutputを、次のコマンドの第一引数に放り込む
- dplyrを読み込むと利用可能
# 使わない書き方
df <- subset(iris, Species == "setosa")
df2 <- subset(df, select = c(Sepal.Length, Sepal.Width))
head(df2, 2)
## # A tibble: 2 x 2
## Sepal.Length Sepal.Width
## * <dbl> <dbl>
## 1 5.1 3.5
## 2 4.9 3.0
# 使った書き方
(df <- subset(iris, Species == "setosa") %>%
subset(select = c(Sepal.Length, Sepal.Width)) %>%
head(2))
## # A tibble: 2 x 2
## Sepal.Length Sepal.Width
## * <dbl> <dbl>
## 1 5.1 3.5
## 2 4.9 3.0
ポイント
メリット
- 流れるようにコードがかける
- 引き渡しのためにわざわざオブジェクトを作る必要がない
混乱やメモリを抑制できる
- RStudioにショートカットがある(Ctrl/Cmd + Shift + M)
- dplyrやtidyrとの相性が非常にいい
デメリット
- 第一引数に投入されるため、使用できる関数に制限あり
明示的に放り込む方法はあるが割愛
- (人によっては)掴みづらい
変数(列)の選択
dplyr::select
df <- dplyr::select(iris, c(Sepal.Width,Species))
head(df, 3)
## # A tibble: 3 x 2
## Sepal.Width Species
## * <dbl> <fctr>
## 1 3.5 setosa
## 2 3.0 setosa
## 3 3.2 setosa
- dplyr::select(データフレーム, 列の指定, …)
- 列の指定方法は、基本subsetと同様
- 列の指定については、さらに特別な関数が利用可能
列選択用関数: starts_with()
df <- dplyr::select(iris, starts_with("sepal"))
head(df, 3)
## # A tibble: 3 x 2
## Sepal.Length Sepal.Width
## * <dbl> <dbl>
## 1 5.1 3.5
## 2 4.9 3.0
## 3 4.7 3.2
- start_with(x, ignore.case = TRUE)
- 前方一致で変数を検索してもってくる
- なお
ignore.case = FALSE
にすると、大文字と小文字を区別してくれる
列選択用関数: ends_with()
df <- dplyr::select(iris, ends_with("width"))
head(df, 3)
## # A tibble: 3 x 2
## Sepal.Width Petal.Width
## * <dbl> <dbl>
## 1 3.5 0.2
## 2 3.0 0.2
## 3 3.2 0.2
- ends_with(x, ignore.case = TRUE)
- 後方一致で変数を検索して持ってくる
列選択用関数: contains()
df <- dplyr::select(iris, contains("pe"))
head(df, 3)
## # A tibble: 3 x 3
## Petal.Length Petal.Width Species
## * <dbl> <dbl> <fctr>
## 1 1.4 0.2 setosa
## 2 1.4 0.2 setosa
## 3 1.3 0.2 setosa
- contains(x, ignore.case = TRUE)
- 部分一致で変数を検索して持ってくる
列選択用関数: matches()
df <- dplyr::select(iris, matches(".t."))
head(df, 3)
## # A tibble: 3 x 4
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## * <dbl> <dbl> <dbl> <dbl>
## 1 5.1 3.5 1.4 0.2
## 2 4.9 3.0 1.4 0.2
## 3 4.7 3.2 1.3 0.2
- matches(x, ignore.case = TRUE)
- 正規表現で指定してマッチする変数を持ってくる
列選択用関数: num_range()
df <- as.data.frame(matrix(1:30, nrow = 3, ncol = 10))
colnames(df) <- c(paste0("beer", 1:5), paste0("sake0", 1:5))
ls(df)
## [1] "beer1" "beer2" "beer3" "beer4" "beer5" "sake01" "sake02"
## [8] "sake03" "sake04" "sake05"
dplyr::select(df, num_range("beer", 1:3, 1))
## # A tibble: 3 x 3
## beer1 beer2 beer3
## <int> <int> <int>
## 1 1 4 7
## 2 2 5 8
## 3 3 6 9
dplyr::select(df, num_range("sake", 2:4, 2))
## # A tibble: 3 x 3
## sake02 sake03 sake04
## <int> <int> <int>
## 1 19 22 25
## 2 20 23 26
## 3 21 24 27
- num_range(“文字列”, 対象の数値, 桁数)
- “beer1からbeer3まで”といった指定方法。桁数があるのがGood!
列選択用関数: one_of()
vname <- c("Petal.Length", "Sepal.Width")
df <- dplyr::select(iris, one_of(vname))
head(df, 3)
## # A tibble: 3 x 2
## Petal.Length Sepal.Width
## * <dbl> <dbl>
## 1 1.4 3.5
## 2 1.4 3.0
## 3 1.3 3.2
- 変数名を文字列ベクトルでまとめて渡す時に使用。
- これで挟み込まずにそのままベクトルを指定してもエラーが出る
列選択用関数: everything()
df <- as.data.frame(matrix(1:15, nrow = 3, ncol = 5))
colnames(df) <- c("touyama", "hanazawa", "komatsu", "asumi", "sakura")
dplyr::select(df, everything())
## # A tibble: 3 x 5
## touyama hanazawa komatsu asumi sakura
## <int> <int> <int> <int> <int>
## 1 1 4 7 10 13
## 2 2 5 8 11 14
## 3 3 6 9 12 15
dplyr::select(df, hanazawa, touyama, everything())
## # A tibble: 3 x 5
## hanazawa touyama komatsu asumi sakura
## <int> <int> <int> <int> <int>
## 1 4 1 7 10 13
## 2 5 2 8 11 14
## 3 6 3 9 12 15
こういう使い方も。
head(dplyr::select(iris, kosaki=starts_with("Petal"), everything()))
## # A tibble: 6 x 5
## kosaki1 kosaki2 Sepal.Length Sepal.Width Species
## * <dbl> <dbl> <dbl> <dbl> <fctr>
## 1 1.4 0.2 5.1 3.5 setosa
## 2 1.4 0.2 4.9 3.0 setosa
## 3 1.3 0.2 4.7 3.2 setosa
## 4 1.5 0.2 4.6 3.1 setosa
## 5 1.4 0.2 5.0 3.6 setosa
## 6 1.7 0.4 5.4 3.9 setosa
変数(列)を新規で作成、更新
dplyr::mutate()
df <- dplyr::mutate(iris, beer=Sepal.Width*2)
head(df, 2)
## # A tibble: 2 x 6
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species beer
## * <dbl> <dbl> <dbl> <dbl> <fctr> <dbl>
## 1 5.1 3.5 1.4 0.2 setosa 7
## 2 4.9 3.0 1.4 0.2 setosa 6
df <- dplyr::mutate(df, beer=Sepal.Width*3)
head(df, 2)
## # A tibble: 2 x 6
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species beer
## * <dbl> <dbl> <dbl> <dbl> <fctr> <dbl>
## 1 5.1 3.5 1.4 0.2 setosa 10.5
## 2 4.9 3.0 1.4 0.2 setosa 9.0
- dplyr::mutate(データフレーム、変数名=処理内容)
- データフレームに新たに列を追加します
- 変数名に既存の変数を指定すると上書きします
dplyr::mutate_each()
df <- dplyr::mutate_each(iris, funs(. * 2), -Species)
## `mutate_each()` is deprecated.
## Use `mutate_all()`, `mutate_at()` or `mutate_if()` instead.
## To map `funs` over a selection of variables, use `mutate_at()`
kable(head(df,2))
10.2 |
7 |
2.8 |
0.4 |
setosa |
9.8 |
6 |
2.8 |
0.4 |
setosa |
- dplyr::mutate_each(データフレーム、関数, …)
- 複数の列に、関数の内容を一気にあてます
- …のところで変数を指定します
(参考)その他のmutate関連関数
- mutate_if(), mutate_at(), mutate_all()が追加されています
- dplyrを最新にして,ヘルプで確認してみてください
レコード(行)を条件により抽出、並べ替え
dplyr::filter()
df <- dplyr::filter(iris, Species=='virginica')
head(df, 3)
## # A tibble: 3 x 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## * <dbl> <dbl> <dbl> <dbl> <fctr>
## 1 6.3 3.3 6.0 2.5 virginica
## 2 5.8 2.7 5.1 1.9 virginica
## 3 7.1 3.0 5.9 2.1 virginica
- dplyr::filter(データフレーム, 条件式)
- 使い方はsubset()と同様
dplyr::arrange()
df <- dplyr::arrange(iris, Sepal.Length)
head(df, 3)
## # A tibble: 3 x 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## * <dbl> <dbl> <dbl> <dbl> <fctr>
## 1 4.3 3.0 1.1 0.1 setosa
## 2 4.4 2.9 1.4 0.2 setosa
## 3 4.4 3.0 1.3 0.2 setosa
df <- dplyr::arrange(df, desc(Sepal.Length))
head(df, 3)
## # A tibble: 3 x 5
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## * <dbl> <dbl> <dbl> <dbl> <fctr>
## 1 7.9 3.8 6.4 2.0 virginica
## 2 7.7 3.8 6.7 2.2 virginica
## 3 7.7 2.6 6.9 2.3 virginica
- dplyr::arrange(データフレーム, キー列)で昇順
- dplyr::arrange(データフレーム, desc(キー列))で降順
データを集計(要約)
dplyr::summarize()
df <- dplyr::summarize(iris, varmean=mean(Sepal.Length))
df
## # A tibble: 1 x 1
## varmean
## <dbl>
## 1 5.843333
- dplyr::summarize(データフレーム, 新変数名=関数(処理対象の変数名))
- 列の集計を算出
- 使える関数はsum,sd,meanなど
dplyr::summarize_each()
df <- dplyr::summarize_each(iris, funs(min, mean, max, sd), ends_with("Length"))
## `summarise_each()` is deprecated.
## Use `summarise_all()`, `summarise_at()` or `summarise_if()` instead.
## To map `funs` over a selection of variables, use `summarise_at()`
df
## # A tibble: 1 x 8
## Sepal.Length_min Petal.Length_min Sepal.Length_mean Petal.Length_mean
## <dbl> <dbl> <dbl> <dbl>
## 1 4.3 1 5.843333 3.758
## # ... with 4 more variables: Sepal.Length_max <dbl>,
## # Petal.Length_max <dbl>, Sepal.Length_sd <dbl>, Petal.Length_sd <dbl>
- dplyr::summarize_each(データフレーム, funs(関数), 変数)
- 変数で指定した各変数に対して、関数で集計した結果を返します
- 変数の指定には、dplyr::select()での方法がそのまま使えます
(参考)その他のsummarize関連関数
- summarize_if(), summarize_at(), summarize_all()が追加されています
- dplyrを最新にして,ヘルプで確認してみてください
複数のデータセットを結合
データセットの準備
a <- data.frame(x1=c("A","B","C"),x2=1:3)
b <- data.frame(x1=c("A","B","D"),x3=c(TRUE, FALSE, TRUE))
y <- data.frame(x1=c("A","B","C"),x2=1:3)
z <- data.frame(x1=c("B","C","D"),x2=2:4)
- aとbを結合する場合、共通する変数はx1
x1をキーにして、mergeします
- yとzを結合する場合、変数は共通です 行を追加してまとめる、あるいは列を追加してまとめます
dplyr::full_join()
df <- dplyr::full_join(a,b,by="x1")
## Warning: Column `x1` joining factors with different levels, coercing to
## character vector
kable(df)
A |
1 |
TRUE |
B |
2 |
FALSE |
C |
3 |
NA |
D |
NA |
TRUE |
- dplyr::full_join(データフレーム1, データフレーム2, by=キー変数)
- 全ての行と列を結合します
- 該当するものがない場合、
NA
がはいります
dplyr::inner_join()
df <- dplyr::inner_join(a,b,by="x1")
## Warning: Column `x1` joining factors with different levels, coercing to
## character vector
kable(df)
- dplyr::full_join(データフレーム1, データフレーム2, by=キー変数)
- 両方のデータフレームに存在する行のみを残して結合します
dplyr::bind_cols()
df <- dplyr::bind_cols(y, z)
kable(df)
- 左のデータフレームに右のデータフレームの列を追加します
- 行数が一致してないとエラーになります
dplyr::bind_rows()
df <- dplyr::bind_rows(y, z)
## Warning in bind_rows_(x, .id): Unequal factor levels: coercing to character
## Warning in bind_rows_(x, .id): binding character and factor vector,
## coercing into character vector
## Warning in bind_rows_(x, .id): binding character and factor vector,
## coercing into character vector
kable(df)
- 左のデータフレームに右のデータフレームの行を追加します
- 列数が一致してないとエラーになります
dplyr::bind_row(…, .id=)
df <- dplyr::bind_rows(y, z, .id = "df_id")
## Warning in bind_rows_(x, .id): Unequal factor levels: coercing to character
## Warning in bind_rows_(x, .id): binding character and factor vector,
## coercing into character vector
## Warning in bind_rows_(x, .id): binding character and factor vector,
## coercing into character vector
kable(df)
1 |
A |
1 |
1 |
B |
2 |
1 |
C |
3 |
2 |
B |
2 |
2 |
C |
3 |
2 |
D |
4 |
- 引数として
.id=**
を指定すると、テーブルidを変数として作成してくれます
- これ、めっちゃ便利です
wide型(横型)とlong型(縦型)を変換
tidyr::gather()
df <- tidyr::gather(data=iris, key = keykey, value = valuevalue, -Species)
kable(head(df, 4))
setosa |
Sepal.Length |
5.1 |
setosa |
Sepal.Length |
4.9 |
setosa |
Sepal.Length |
4.7 |
setosa |
Sepal.Length |
4.6 |
- data: 使用するデータフレーム
- key: まとめた時に、「この行の値はどの変数に入ってたものか」を示す変数。
- value: まとめた変数の値。
- …: まとめる変数を指定します。dplyr::select()のテクニックがそのまま使えます
tidyr::spread()
# irisにID列を追加して、gatherでまとめている
df <- dplyr::mutate(iris, id=rownames(iris)) %>%
tidyr::gather(key = keykey, value = valuevalue, contains("l."))
knitr::kable(head(df,2))
setosa |
1 |
Sepal.Length |
5.1 |
setosa |
2 |
Sepal.Length |
4.9 |
# ひっつけたけどspreadでバラします
df_2 <- tidyr::spread(df, key = keykey, value = valuevalue)
knitr::kable(head(df_2,2))
setosa |
1 |
1.4 |
0.2 |
5.1 |
3.5 |
setosa |
10 |
1.5 |
0.1 |
4.9 |
3.1 |
- gatherと逆の動きをします
- ただし、spreadを実行した後に、主キーとなるような変数が存在する必要があります
- データベース的なものがあるんだと思います
列の結合・分離
tidyr::unite
df <- tidyr::unite(data = iris, col = colll, starts_with("Sepal"), sep = "-")
knitr::kable(head(df))
5.1-3.5 |
1.4 |
0.2 |
setosa |
4.9-3 |
1.4 |
0.2 |
setosa |
4.7-3.2 |
1.3 |
0.2 |
setosa |
4.6-3.1 |
1.5 |
0.2 |
setosa |
5-3.6 |
1.4 |
0.2 |
setosa |
5.4-3.9 |
1.7 |
0.4 |
setosa |
tidyr::separate
# 一旦ひっつけます(uniteのコードと同一)
df <- tidyr::unite(data = iris, col = colll, starts_with("Sepal"), sep = "-")
# separateを実行
df2 <- tidyr::separate(data = df, col = colll, into = c("Sepal.Length","Sepal.Width"), sep = "-")
knitr::kable(head(df2))
5.1 |
3.5 |
1.4 |
0.2 |
setosa |
4.9 |
3 |
1.4 |
0.2 |
setosa |
4.7 |
3.2 |
1.3 |
0.2 |
setosa |
4.6 |
3.1 |
1.5 |
0.2 |
setosa |
5 |
3.6 |
1.4 |
0.2 |
setosa |
5.4 |
3.9 |
1.7 |
0.4 |
setosa |
- 一つの列を、指定した文字で分割して別々の列にします