[英]Join dataframes using an OR condition for columns to match by
假設我們有兩個要加入的數據框。 為簡單起見,假設兩者具有相同的行數,並且一個數據幀中的每一行必須在另一個數據幀中具有唯一的對應行。 這是此設置的 MWE:
library(dplyr)
df1 <- tibble(id1 = 1:3, x = c("b", "a", "b"), y = c(55, 50, 58), z = c(65, 60, 69))
df2 <- tibble(id2 = 11:13, x = c("a", "b", "b"), y = c(50, 55, 59), z = c(61, 66, 69))
# # A tibble: 3 x 4
# id1 x y z
# <int> <chr> <dbl> <dbl>
# 1 1 b 55 65
# 2 2 a 50 60
# 3 3 b 58 69
# # A tibble: 3 x 4
# id2 x y z
# <int> <chr> <dbl> <dbl>
# 1 11 a 50 61
# 2 12 b 55 66
# 3 13 b 59 69
目標是將df1
中的唯一 ID 與df2
唯一但不同的 ID 鏈接起來。 我可以通過利用x
、 y
和z
列中的組合信息足以唯一地標識行這一事實來做到這一點。 下面詳細解釋的問題是,如果我們能夠通過諸如c("x", "y" OR "z")
類的內容進行連接,連接將在此設置中正常工作。
x
列開始,我們有足夠的信息將id1 == 2
與id2==11
,因為它們共享相同的唯一值(即"a"
)。 但是,對於其余的對,僅列x
是不夠的。y
允許我們將id1 == 1
與id2==12
鏈接起來。 但是,列y
(除了x
)將(正確地)不匹配id1 == 3
與id2==13
,因為它們具有不同的y
值。z
允許我將id1 == 3
與id2==13
鏈接起來,但現在我們遇到了與以前相同的問題,現在將id1 == 1
與id2==12
鏈接起來:它們的z
值不同。 此外,如果我們通過z
加入,那么我們會破壞id1 == 2
與id2==11
的鏈接(盡管這個例子在沒有這個額外的怪癖的情況下仍然可以工作)。 因此,問題是,除了在x
嚴格匹配之外,是否有一種好的和/或簡潔的方式在y
和z
列上使用OR
條件連接這兩個數據幀。 就像是
full_join(df1, df2, by = c("x", "y" OR "z"))
到目前為止,我的嘗試涉及一系列連接和其他操作,但讀取起來非常麻煩(這使它容易出錯),而且對於足夠大的數據來說可能太慢了。 我願意對此方法進行更正,或者被告知這是唯一的方法(盡管我真的希望不是)。
left_join(df1, df2, by = c("x", "y"), suffix = c("1", "2")) %>%
left_join(df2, by = c("x", "z1" = "z"), suffix = c("1", "2")) %>%
rowwise() %>%
mutate(id2 = sum(id21, id22, na.rm = T)) %>%
select(id1, id2)
# # A tibble: 3 x 2
# # Rowwise:
# id1 id2
# <int> <int>
# 1 1 12
# 2 2 11
# 3 3 13
您可以使用tidyr
將兩個 data.frames 轉換為長格式。
library(tidyr)
library(dplyr)
df2_2 <- df2 %>%
pivot_longer(c(y, z))
df1_1 <- df1 %>%
pivot_longer(c(y, z))
接下來,您inner_join
都是由你轉動data.frames的x
和新value
列,並把它們放回寬格式。 所以
df1_1 %>%
inner_join(df2_2, by=c("x", "value")) %>%
pivot_wider(names_from="name.x") %>%
select(-name.y)
返回
# A tibble: 3 x 5
id1 x id2 y z
<int> <chr> <int> <dbl> <dbl>
1 1 b 12 55 NA
2 2 a 11 50 NA
3 3 b 13 NA 69
要么
df1_1 %>%
inner_join(df2_2, by=c("x", "value")) %>%
pivot_wider(names_from="name.x") %>%
select(id1, id2)
給你你想要的輸出
# A tibble: 3 x 2
id1 id2
<int> <int>
1 1 12
2 2 11
3 3 13
如果y
和z
是相同類型,這可以正常工作。 如果它們的類型不同(例如一個是字符,另一個是雙pivot_longer
),則必須將它們轉換為通用格式,以便pivot_longer
起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.