【问题标题】:How to merge two data.frame by "or"如何通过 \"or\" 合并两个 data.frame
【发布时间】:2022-11-18 09:39:34
【问题描述】:

我有一个包含下一列 (df1) 的数据框:

Codes Oxy Date
100095 30% 1
100096 50% 1
100097 20% 1
100095 40% 2
100096 10% 2
100097 20% 2

另一个包含我想合并的附加数据 (df2):

Code1 Code2 Spp
100095 345550 Sz
104568 100096 Cg
983488 100097 As

这第二个 df 有额外的信息,但行数不同。如您所见,代码相似但并不总是来自同一列。然后,我想做的是合并两个 df,但说“Codes”=“Code1”或“Code2”。如果代码与两列之一相似,则应合并该行上的其余数据。

我试过:

df3<-merge(x = df1, y = df2, all.x = TRUE)

但它只将所有额外数据复制到每一行而不考虑代码。 希望我解释一下我的自我,非常感谢你。

我希望将 spp 变量添加到两个 df 之间具有相同代码的每一行,但考虑 df2 中的两个代码列之一。

【问题讨论】:

  • 你好,Eduardo,为什么不尝试以这种方式重复 df2:df2 &lt;- rbind(data.frame(Codes=df2$Code1, df2[,-1:-2]), data.frame(Codes=df2$Code2, df2[,-1:-2])) 然后合并结果?

标签: r dataframe dplyr merge


【解决方案1】:

试试这个,基于平等迭代加入:

library(dplyr)
df1 %>%
  left_join(df2, by = c("Codes" = "Code1")) %>%
  left_join(df2, by = c("Codes" = "Code2")) %>%
  mutate(Spp = coalesce(Spp.x, Spp.y)) %>%
  select(-Code1, -Code2, -Spp.x, -Spp.y)
#    Codes Oxy Date Spp
# 1 100095 30%    1  Sz
# 2 100096 50%    1  Cg
# 3 100097 20%    1  As
# 4 100095 40%    2  Sz
# 5 100096 10%    2  Cg
# 6 100097 20%    2  As

或者,我们可以在旋转数据后进行一次连接。这样做的好处是,如果您实际上有超过 2 个 Code# 字段,这将适用于“1 个或更多”,而不是硬编码 2:

tidyr::pivot_longer(df2, -Spp, values_to = "Codes") %>%
  select(-name) %>%
  left_join(df1, ., by = "Codes")
#    Codes Oxy Date Spp
# 1 100095 30%    1  Sz
# 2 100096 50%    1  Cg
# 3 100097 20%    1  As
# 4 100095 40%    2  Sz
# 5 100096 10%    2  Cg
# 6 100097 20%    2  As

一个可能的问题是:如果一个特定代码有多个 Spp,那么这将导致重复行,导致超过 6 行(给定这个 df1)。如果这是一个问题,那么您可能需要执行类似 pivot_longer(...) %&gt;% distinct(Codes, .keep_all = TRUE) %&gt;% left_join(...) 的操作,或者选择另一种缩减方法,这样新的 Codes 列中的任何内容都不会重复。

【讨论】:

    猜你喜欢
    • 2022-11-10
    • 2019-01-25
    • 1970-01-01
    • 2017-05-12
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    • 2015-07-11
    相关资源
    最近更新 更多