joinでテーブル結合(4).R
要約
・semi/anti_joinを使ったjoin前の確認
・引数 suffixの使い道
join関係その他
前回までの記事で書き残したことを、雑多に集めてみた。調べるほど色んなものが出てくる。joinそのものについては、ここで一段落としたい。
semi_join()とanti_join()
左テーブルのうち、右と突き当る予定=joinされるものだけが表示されるのがsemi_join()で、右と突き当らない=joinされないものだけが表示されるのがanti_join()だ。
このとき、出力されるのは左テーブルにある項目だけになる。
例えば、semi_join()とinner_join()では、ともに突き当るものだけが出力されるのだけれども、前者では左テーブルのみ出力され、後者ではjoin結果全体が出力される。
また、semi_join()もanti_join()も、あくまでも左テーブルについてだけ出力するので、右テーブルについても当たる/当たらないを確認したければ左右を入れ替えてあげる必要がある。
いずれにせよ、当たる/当たらないが簡便に確認出来て便利だ。
> semi_join(x, y, c("Kibo" = "ShoCo"))
NO SEX AGE ShoCo Kibo
1 1 男 26 1 2
2 3 女 27 4 3
3 4 男 25 5 1
4 5 女 24 5 4
5 6 女 29 3 1
> anti_join(x, y, c("Kibo" = "ShoCo"))
NO SEX AGE ShoCo Kibo
1 2 男 28 3 6
> semi_join(y, x, c("ShoCo" = "Kibo"))
ShoCo ShoMei
1 1 総務部
2 2 経理部
3 3 営業部
4 4 設計部
> anti_join(y, x, c("ShoCo" = "Kibo"))
ShoCo ShoMei
1 5 生産部
引数 suffix
mutating joinの4関数の引数ではあるものの、以前の記事では記載を省略した。備忘として残しておく。
suffixについては、まず以下のようにパイプ処理で2段階にjoinしたものを見てほしい。1段目で左テーブルのShoCoを、2段目でKiboをキーにしてjoinしている。
ShoMeiの後ろに.xまたは.yがくっついて出力されているのが分かる。これがsuffixだ。2段階で処理をしているが、いずれも右テーブルにあったShoMei列が追加される。
これでは列名が重複して一意の名前にならないので、自動でsuffixを付けることで一意になるようにしてくれている。
この場合、1段目のjoinで生成しているはずのShoMei列が2段目の左テーブルとして入力されているので、すでにある方がShoMei.x、右テーブルからさらにjoinされる方がShoMei.yという名前になる。
x, yは単に由来するのが左か右かだけで決まる。
やってみると分かるのだけど、テーブルの名前がsuffixになるわけではない。なってくれてよかったのに……いやパイプ処理があると命名規則でもめるかな。
使い道としては、例えばキー列の名前を使って、suffix = c(".ShoCo", ".Kibo") のように指定することで何をキーにしたときの結果なのか、suffixを見てわかるようになる。
> left_join(x, y) %>% left_join(., y, by = c("Kibo" = "ShoCo"))
Joining, by = "ShoCo"
NO SEX AGE ShoCo Kibo ShoMei.x ShoMei.y
1 1 男 26 1 2 総務部 経理部
2 2 男 28 3 6 営業部 <NA>
3 3 女 27 4 3 設計部 営業部
4 4 男 25 5 1 生産部 総務部
5 5 女 24 5 4 生産部 設計部
6 6 女 29 3 1 営業部 総務部
> z <- x
> left_join(z, y) %>% left_join(., y, by = c("Kibo" = "ShoCo"))
Joining, by = "ShoCo"
NO SEX AGE ShoCo Kibo ShoMei.x ShoMei.y
1 1 男 26 1 2 総務部 経理部
2 2 男 28 3 6 営業部 <NA>
3 3 女 27 4 3 設計部 営業部
4 4 男 25 5 1 生産部 総務部
5 5 女 24 5 4 生産部 設計部
6 6 女 29 3 1 営業部 総務部
> left_join(x, y) %>% left_join(., y, by = c("Kibo" = "ShoCo"), suffix = c(".ShoCo",".Kibo"))
Joining, by = "ShoCo"
NO SEX AGE ShoCo Kibo ShoMei.ShoCo ShoMei.Kibo
1 1 男 26 1 2 総務部 経理部
2 2 男 28 3 6 営業部 <NA>
3 3 女 27 4 3 設計部 営業部
4 4 男 25 5 1 生産部 総務部
5 5 女 24 5 4 生産部 設計部
6 6 女 29 3 1 営業部 総務部
実はそれ以外にcopyという引数を指定することができる(デフォルトはcopy = F)。
ところが、これがいまいちよくわからない。何しろ、dplyr::のチートシート(パッケージ内の各関数の概要が載ってるもの)を見ても、copyの項がない。suffixは書いてあるのに。チートシートを見ても、ちいとも分からない。
さておき、copy = Tを指定すると「データソースが異なる際にxにyをコピーすることができる」らしい。とはいうものの、やってみても出力は変化しない。
下記を流し読みした限りでは、おそらく各テーブルを外部のDB(=データソース)とリンクさせてるときに、どちらかのDBに対して一時テーブルを作れるよう要求している感じがある(反対に、copy = FならRを実行しているPCのメモリに両方のテーブルのを持ってきている?)
まあ、INSERTの権限云々言ってるから、普段相手にしてるデータソースでは権限なかった気がするので、そもそも一度ローカルに取り込んでからじゃないと無理かなあ(i.e. 出番がない AND 権限気を付けなきゃ)。
あと詳しそうな人の記事に、重くなるから気を付けろって書いてあった。
以上。
この記事が気に入ったらサポートをしてみませんか?