dplyrで結合するときにxとyの列の名前を指定するにはどうすればよいですか?


91

dplyrを使用して結合したい2つのデータフレームがあります。1つは、名を含むデータフレームです。

test_data <- data.frame(first_name = c("john", "bill", "madison", "abby", "zzz"),
                        stringsAsFactors = FALSE)

もう1つのデータフレームには、性別を識別するKantrowitz名コーパスのクリーンアップバージョンが含まれています。最小限の例を次に示します。

kantrowitz <- structure(list(name = c("john", "bill", "madison", "abby", "thomas"), gender = c("M", "either", "M", "either", "M")), .Names = c("name", "gender"), row.names = c(NA, 5L), class = c("tbl_df", "tbl", "data.frame"))

基本的に、test_dataテーブルを使用してkantrowitzテーブルから名前の性別を調べたいと思います。私は関数にこの抽象化するつもりですのでencode_gender、私が使用することになるだろう、データセット内の列の名前を知らないだろう、と私はそれがであることを保証することはできませんので、nameのように、kantrowitz$name

ベースRIでは、次のようにマージを実行します。

merge(test_data, kantrowitz, by.x = "first_names", by.y = "name", all.x = TRUE)

これにより、正しい出力が返されます。

  first_name gender
1       abby either
2       bill either
3       john      M
4    madison      M
5        zzz   <NA>

しかし、他のすべてのデータ操作にそのパッケージを使用しているので、dplyrでこれを実行したいと思います。byさまざまな*_join関数のdplyrオプションでは、1つの列名しか指定できませんが、2つ指定する必要があります。私はこのようなものを探しています:

library(dplyr)
# either
left_join(test_data, kantrowitz, by.x = "first_name", by.y = "name")
# or
left_join(test_data, kantrowitz, by = c("first_name", "name"))

dplyrを使用してこの種の結合を実行する方法は何ですか?

(カントロウィッツコーパスは性別を特定するための悪い方法であることを気にしないでください。私はより良い実装に取り​​組んでいますが、これを最初に機能させたいと思っています。)


3
現在はできませんが、やることリストに載っています:github.com/hadley/dplyr/issues/177
hadley

回答:


153

この機能はdplyrv0.3で追加されました。名前付き文字ベクトルを(およびその他の結合関数)のby引数に渡しleft_joinて、各データフレームで結合する列を指定できるようになりました。元の質問の例では、コードは次のようになります。

left_join(test_data, kantrowitz, by = c("first_name" = "name"))

13
編集これは一般的な場合にも機能します: left_join(data_a, data_b, by = c("a.first" = "b.first", "a.second" = "b.second", "a.third" = "b.third"))
davidski 2016

by =オプションです。あなたができることleft_join(test_data, kantrowitz, c("first_name" = "name"))
Pranay Aryal 2017

11
これは、関数に対するどの引数にも当てはまります。しかし、私は一般的に、この場合、位置の一致よりも名前付きの引数を使用して明示する方が良いと思います。
リンカーンマレン2017

5

これは、実際の解決策というよりも回避策です。test_data別の列名で新しいオブジェクトを作成できます。

left_join("names<-"(test_data, "name"), kantrowitz, by = "name")

     name gender
1    john      M
2    bill either
3 madison      M
4    abby either
5     zzz   <NA>

名前を変更するとコピーが作成されると思います。これは、dplyrがそれを回避し、代わりに実行する方法である可能性があります。
joran 2014

2
0.1.2では、少なくとも実行できるようにselect(test_data, first_name = name)なり、浅いコピーしか作成されません。
ハドリー2014

1
使用しdata.table::setnamesますか?
ヒュー

2
ソリューションselect(test_data、first_name = name)は、2014年6月の時点では機能しません
userJT
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.