与 data.table 合并时防止重复列
Preventing duplicate columns when merging with data.table
我有两个数据表,它们的列名部分相似:
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
我们可以创建与 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'))
我有两个数据表,它们的列名部分相似:
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
我们可以创建与 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'))