合并非关键变量的所有“出现次数”
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了合并非关键变量的所有“出现次数”相关的知识,希望对你有一定的参考价值。
我有两个数据集,我想要的可能被宽泛地称为“非关键变量的外连接”。
这是数据集
数据集1
oc oc2 state_id r_state
A011 A01 1808 1.00
A011 A01 1810 0.50
A012 A01 1810 0.50
A011 A01 1814 0.33
A012 A01 1814 0.33
A013 A01 1814 0.33
数据集2
oc r_country
A011 0.62
A012 0.14
A013 0.24
我想要的输出如下:
oc oc2 state_id r_state r_country
A011 A01 1808 1.00 0.62
A012 A01 1808 NA 0.14
A013 A01 1808 NA 0.24
A011 A01 1810 0.50 0.62
A012 A01 1810 0.50 0.14
A013 A01 1810 NA 0.24
A011 A01 1814 0.33 0.62
A012 A01 1814 0.33 0.62
A013 A01 1814 0.33 0.24
注意如何“人为地”引入行号2,3和6。我的问题是如何在R中执行此操作。如果我通过oc
合并,merge
函数将不会创建这些行。如果我通过oc2
合并,它将创建不必要的额外行。请注意,oc2
只是oc
的更高级编码。下面是几行代码,用于在data.tables中获取上述数据集。请注意,这些是样本数据集,实际数据包含大约50种不同的oc2
,每个oc2
可以包含1到9个oc
。此外,还有47个不同的州。
DT1 = data.table(oc = c('A011','A011','A012','A011','A012','A013'),
oc2 = rep('A01',6),
state_id = c(1808,1810,1810,1814,1814,1814),
r_state = c(1, 0.5,0.5,0.33,0.33,0.33)
)
DT2 = data.table(oc = c('A011','A012','A013'),
r_country = c(0.62, 0.14, 0.24)
)
虽然我使用的是data.table
,但基础data.frame
解决方案也可以。
答案
使用:
library(zoo) # for the 'na.locf'-function
DT1[CJ(oc = oc, state_id = state_id, unique = TRUE), on = .(oc, state_id)
][order(state_id), oc2 := na.locf(oc2), by = 'state_id'
][DT2, on = 'oc', r_country := r_country][order(state_id)]
得到:
oc oc2 state_id r_state r_country 1: A011 A01 1808 1.00 0.62 2: A012 A01 1808 NA 0.14 3: A013 A01 1808 NA 0.24 4: A011 A01 1810 0.50 0.62 5: A012 A01 1810 0.50 0.14 6: A013 A01 1810 NA 0.24 7: A011 A01 1814 0.33 0.62 8: A012 A01 1814 0.33 0.14 9: A013 A01 1814 0.33 0.24
根据@ Frank的建议,您也可以在不使用na.locf
-package的zoo
的情况下执行此操作:
DT1[CJ(oc = oc, state_id = state_id, unique = TRUE), on = .(oc, state_id)
][DT2, on = .(oc), r_country := i.r_country][DT1, on = .(state_id), oc2 := i.oc2][]
另一答案
这可以表示为使用三连接的单个SQL语句,它将这四个表连接在一起:
oc
,由独特的oc
值组成,state_id
,由独特的state_id
值组成,DT1
和DT2
使用此代码:
library(sqldf)
sql <- "
with
oc as (select distinct oc from DT1),
state_id as (select distinct state_id from DT1)
select *
from oc
join state_id
left join DT1 using (oc, state_id)
left join DT2 using (oc)
order by state_id, oc"
sqldf(sql)
给出这个输出:
oc state_id oc2 r_state r_country
1 A011 1808 A01 1.00 0.62
2 A012 1808 <NA> NA 0.14
3 A013 1808 <NA> NA 0.24
4 A011 1810 A01 0.50 0.62
5 A012 1810 A01 0.50 0.14
6 A013 1810 <NA> NA 0.24
7 A011 1814 A01 0.33 0.62
8 A012 1814 A01 0.33 0.14
9 A013 1814 A01 0.33 0.24
以上是关于合并非关键变量的所有“出现次数”的主要内容,如果未能解决你的问题,请参考以下文章