【问题标题】:Combining two dataframes, similar rows, similar columns except one colum has different values结合两个数据框,相似的行,相似的列,除了一列具有不同的值
【发布时间】:2020-05-19 19:03:27
【问题描述】:

我有两个要合并为一个的数据框。一个数据框中的行并不总是在另一个数据框中,反之亦然。我想保留两个数据集中的所有行和列。此外,有一列(“Tag”)有时对同一行感兴趣(“ID”)具有不同的值。我的数据集太大,无法手动找到它们。当“标签”中的值不相同时,我很难创建一个单独的列。我尝试过test.output1 <-union(test.df1, test.df2,suffix=c(".1",".2")),但由于某些相同的列具有不同的因子水平而出现错误。我也尝试过以下变体:test.output2<-rbind.fill(test.df1, test.df2),但最终出现重复行。

非常感谢任何帮助。谢谢!

例子:

#dataframe 1
test.df1
ID     Year   Location Tag    Length
H1     2013   Site1    272   46
H2     2013   Site2    236   984
H3     2014   Site3    150   68
H4     2014   Site4    698   12
H34    2015   Site1    594   65

#dataframe 3
test.df2
ID     Year   Species Tag    
H1     2013   1       631 
H2     2013   2       236
H3     2014   3       755
H4     2014   4       698
H12    2017   3       135

#What I would like the output to be
test.df.3 
ID     Year   Location  Species Tag.1   Tag.2  Length
H1     2013   Site1     1       272     631    46
H2     2013   Site2     2       236     NA     984
H3     2014   Site3     3       150     755    68
H4     2014   Site4     4       698     NA     12
H12    2017   NA        3       NA      135    NA
H34    2015   Site1     NA      594     NA     65

【问题讨论】:

  • 您可能会使用dplyr::left_join(test.df1, test.df2, by = c("ID", "Year"))。在函数中,您也可以显式声明添加到具有匹配名称的列的后缀(即标记)。这假设每一行至少有一个 ID 和 Year 可用于配对。
  • 你可以使用merge from base R merge(test.df1, test.df2, by = c('ID', 'Year'), all = TRUE)
  • 我也一直在看,@akrun,但输出不同......不确定它是 OP 还是其他什么。
  • H12/Length如何得到20的值?
  • 我在test.df1 中有不在test.df2 中的行,反之亦然,所以left_join ()right_join () 函数删除了我需要保留的行。 merge() 保留两个数据帧中的所有行

标签: r


【解决方案1】:

联合或行连接会给你十行,我认为这不是你需要的。它也不会分隔 Tag 列。

我认为您需要merge 或加入操作。

merge(test.df1, test.df2, by = c("ID", "Year"), all=TRUE)
#    ID Year Location Tag.x Length Species Tag.y
# 1  H1 2013    Site1   272     46       1   631
# 2 H12 2017     <NA>    NA     NA       3   135
# 3  H2 2013    Site2   236    984       2   236
# 4  H3 2014    Site3   150     68       3   755
# 5 H34 2015    Site1   594     65      NA    NA
# 6  H4 2014    Site4   698     12       4   698

这与您在问题中列出的不同,但我认为前提是正确的。

编辑。更接近您的问题,在这里我们将Tag.y 更新为NA,它与Tag.x 匹配。

out <- merge(test.df1, test.df2, by = c("ID", "Year"), all=TRUE)
out <- within(out, { Tag.y[Tag.x == Tag.y] = NA_integer_ })
out
#    ID Year Location Tag.x Length Species Tag.y
# 1  H1 2013    Site1   272     46       1   631
# 2 H12 2017     <NA>    NA     NA       3   135
# 3  H2 2013    Site2   236    984       2    NA
# 4  H3 2014    Site3   150     68       3   755
# 5 H34 2015    Site1   594     65      NA    NA
# 6  H4 2014    Site4   698     12       4    NA

【讨论】:

  • 谢谢,这很有帮助!我一直在尝试join() 功能,但我想保留的行会被删除。我更正了输出。 H12/Tag.y 不应该是 NA
  • 哪个join函数?有几种。在这种用法中,我倾向于full_join(test1.df, test2.df, by = c("ID", "Year")) %&gt;% ...,就像@Gallarus 在他们的回答中一样。
【解决方案2】:

或者使用dplyr 并删除重复项,因此如果tag.x == tag.y 则仅保留tag.x

library(dplyr)    
test.df3 <- full_join(test.df1, test.df2, by = c("ID", "Year")) %>%
  mutate(tag.y = if_else(tag.x == tag.y, NA_integer_, tag.y))

【讨论】:

  • 由于您使用的是dplyr,我建议使用dplyr::if_else 代替基础ifelse,因为它对类有更好的保护。 (在这种情况下,顺便说一句,它会抱怨,因为NA 在技术上是"logical" 类,而Tag.* 列都是"integer"。“正确”的方法是文字NA_integer_,或者像tag.y[NA] 这样的技巧,它返回NA 的正确变体。)
  • 感谢您的提示(你们俩)!实际上,我确实有一些行 tag.xtag.y 是相同的值
猜你喜欢
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 2022-12-21
  • 1970-01-01
  • 2018-12-19
  • 1970-01-01
  • 2021-02-22
  • 2012-03-13
相关资源
最近更新 更多