問題: 我想加入 2 張桌子。但是,我希望將第二個連接到第一個的列將取決于成功決議第二個資料幀以確定要連接的列和行。
請求: 我已經找到了問題的解決方案(見下文),但在我看來它的計算效率并不高。對于下面的可重現示例來說這不是問題,但在處理更大規模的問題(即~200,000 行/觀察)時可能不太理想。
想知道是否有人可以幫助識別更好的東西——最好是利用 dplyr 的功能。
可重現的例子:
# Equipment alias table
alias1 <- c('a1a1', 'a2a2', 'a3a3', 'a4a4', 'a5a5', 'a6a6')
alias2 <- c('bc001', 'bc002', 'bc003', 'bc004', 'bc005', 'bc006')
alias3 <- c('e1o1', 'e202', 'e303', 'e404', 'e505', 'e606')
df_alias <- data.frame(alias1, alias2, alias3)
# Attribute table
equip <- c('a1a1','bc006', 'e404')
att1 <- c('a', 'b', 'c')
att2 <- c('1', '2', '3')
df_att <- data.frame(equip, att1, att2)
期望的結果:
我希望實作以下目標......
# DESRIED OUTPUT - combining equipment alias table into attribute table based on string match between attibute_equip and any one of columns in equipment alias
equip <- c('a1a1','bc006', 'e404')
att1 <- c('a', 'b', 'c')
att2 <- c('1', '2', '3')
alias1 <- c('a1a1','a6a6', 'a4a4')
alias2 <- c('bc001','bc006', 'bc004')
alias3 <- c('e1o1','e606', 'e404')
df_att <- data.frame(equip, att1, att2, alias1, alias2, alias3)
當前解決方案:
library(dplyr)
left_join(df_att, df_alias, by = character()) %>%
filter(equip == alias1 | equip == alias2 | equip == alias3)
有效但并不完全優雅,因為最終會應用大量重復過濾器來撤消該重復。
uj5u.com熱心網友回復:
一個選項是filter使用if_any然后將子集行與df_att
library(dplyr)
df_att2 <- df_alias %>%
filter(if_any(everything(), ~ .x %in% df_att$equip)) %>%
arrange(na.omit(unlist(across(everything(), ~ match(df_att$equip, .x))))) %>%
bind_cols(df_att, .)
-檢查 OP 的預期(將物件名稱“df_att”更改為“out”以避免任何混淆)
> all.equal(df_att2, out)
[1] TRUE
uj5u.com熱心網友回復:
我不知道它如何比較效率,但一個想法是旋轉每個別名的副本,以便您可以left_join針對單個列而不是多個列。
library(tidyr)
library(dplyr)
df_alias %>%
mutate(across(everything(), ~., .names = "_{.col}")) %>%
pivot_longer(starts_with('_'), names_to = NULL, values_to = 'equip') %>%
left_join(df_att, .)
#> Joining, by = "equip"
#> equip att1 att2 alias1 alias2 alias3
#> 1 a1a1 a 1 a1a1 bc001 e1o1
#> 2 bc006 b 2 a6a6 bc006 e606
#> 3 e404 c 3 a4a4 bc004 e404
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/474669.html
