【问题标题】:Preventing duplicate columns when merging with data.table与 data.table 合并时防止重复列
【发布时间】:2019-05-28 07:45:03
【问题描述】:

我有两个列名部分相似的数据表:

   dfA <- read.table(
  text = "A   B   C   D   E   F   G   iso   year   matchcode
  1   0   1   1   1   0   1   0   NLD   2010   NLD2010
  2   1   0   0   0   1   0   1   NLD   2014   NLD2014
  3   0   0   0   1   1   0   0   AUS   2010   AUS2010
  4   1   0   1   0   0   1   0   AUS   2006   AUS2006
  5   0   1   0   1   0   1   1   USA   2008   USA2008
  6   0   0   1   0   0   0   1   USA   2010   USA2010
  7   0   1   0   1   0   0   0   USA   2012   USA2012
  8   1   0   1   0   0   1   0   BLG   2008   BLG2008
  9   0   1   0   1   1   0   1   BEL   2008   BEL2008
  10   1   0   1   0   0   1   0  BEL   2010   BEL2010",
  header = TRUE
)

   dfB <- read.table(
  text = "A   B   C   D   H   I   J   iso   year   matchcode
  1   0   1   1   1   0   1   0   NLD   2009   NLD2009
  2   1   0   0   0   1   0   1   NLD   2014   NLD2014
  3   0   0   0   1   1   0   0   AUS   2011   AUS2011
  4   1   0   1   0   0   1   0   AUS   2007   AUS2007
  5   0   1   0   1   0   1   1   USA   2007   USA2007
  6   0   0   1   0   0   0   1   USA   2011   USA2010
  7   0   1   0   1   0   0   0   USA   2013   USA2013
  8   1   0   1   0   0   1   0   BLG   2007   BLG2007
  9   0   1   0   1   1   0   1   BEL   2009   BEL2009
  10   1   0   1   0   0   1   0  BEL   2012   BEL2012",
  header = TRUE
)
library(data.table)
setDT(dfA)
setDT(dfB)

要合并 data.tables,我将执行以下操作:

dfA <- dfA[dfB, on = .(iso, year), roll = "nearest", nomatch = 0]

但是,除了所需的重复列matchcode 之外,这还会创建不需要的重复列A, B, C, D。由于我需要进行大量合并,这会变得过于混乱。

有没有办法从合并过程中排除重复的列而不明确引用它们?如果没有,我该如何通过明确引用它们来做到这一点。如果没有,我可以在不明确提及重复项的情况下删除它们吗?例如,通过删除所有看起来像 `i.columnname' 的列?

首选输出如下:

#    A B C D E F G iso year matchcodeA H I J matchcodeB
# 1: 1 0 0 0 1 0 1 NLD  2014  NLD2014  1 0 1    NLD2014
# 2: 0 0 0 1 1 0 0 AUS  2011  AUS2010  1 0 0    AUS2011
# 3: 1 0 1 0 0 1 0 AUS  2007  AUS2006  0 1 0    AUS2007
# 4: 0 0 1 0 0 0 1 USA  2011  USA2010  0 0 1    USA2010
# 5: 0 1 0 1 0 0 0 USA  2013  USA2012  0 0 0    USA2013
# 6: 0 1 0 1 1 0 1 BEL  2009  BEL2008  1 0 1    BEL2009
# 7: 0 1 1 1 0 1 0 NLD  2009  NLD2010  0 1 0    NLD2009
# 8: 0 1 0 1 0 1 1 USA  2007  USA2008  0 1 1    USA2007
# 9: 0 1 0 1 0 0 0 USA  2011  USA2012  0 0 1    USA2010
#10: 1 0 1 0 0 1 0 BEL  2009  BEL2010  1 0 1    BEL2009

【问题讨论】:

  • 对于这个错误我深表歉意,我真的很快就手工制作了表格,因为我的 R 现在正在运行巨大的估算,所以我无法在接下来的几个小时内使用它。如果匹配码在那里就足够了!
  • 没关系。我还以为是错别字

标签: r merge duplicates data.table columnname


【解决方案1】:

我们可以创建与intersecgt 通用的列名的索引

nm1 <- intersect(names(dfA), names(dfB))

然后,使用setdiff 查找在“dfB”中找到的列名,而不是在“nm1”中,同时包括连接列“iso”“year”以及“matchcode”

nm2 <- c(setdiff(names(dfB), nm1), "iso", "year", "matchcode")

现在,我们进行连接

out <- dfA[dfB[, ..nm2], on = .(iso, year), roll = "nearest", nomatch = 0]
setnames(out, c('matchcode', 'i.matchcode'), c('matchcodeA', 'matchcodeB'))

【讨论】:

  • 这是很棒的 akrun,非常感谢!我想我可以手动从列名索引中删除 matchcode 列以保持该信息正确?
  • @Tom 我以为你也不需要matchcode。我对其进行了编辑以包含该列
  • 非常感谢!在问了我的问题后,我才意识到我可能想保留这些信息。
  • 嗨,akrun,我有一个小问题。我一直在尝试将您的解决方案(以及我自己在这篇文章中的尝试)应用到一些数据库。我注意到它大大减少了观察次数。显然它并没有完全按照我的想法去做(只是将信息添加到其他行)。我真的不知道为什么..你有什么想法吗?
  • 如果isoyear 在数据集中不是唯一的,它是否可能不起作用?我开始只是简单地做:dfA&lt;- merge(dfA, dfB, by= "matchcode", all.x = TRUE, allow.cartesian=FALSE)
猜你喜欢
  • 2017-10-01
  • 2019-11-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 2015-02-27
  • 2013-07-08
  • 1970-01-01
相关资源
最近更新 更多