合并非关键变量的所有"出现次数"

Gau*_*hal 4 merge r outer-join data.table

我有两个数据集,我想要的可能被宽泛地称为"非关键变量的外连接".

这是数据集

数据集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    
Run Code Online (Sandbox Code Playgroud)

数据集2

oc  r_country
A011    0.62
A012    0.14
A013    0.24
Run Code Online (Sandbox Code Playgroud)

我想要的输出如下:

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
Run Code Online (Sandbox Code Playgroud)

注意如何"人为地"引入行号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)
                )
Run Code Online (Sandbox Code Playgroud)

虽然我正在使用data.table,但基础data.frame解决方案也会这样做.

Jaa*_*aap 5

使用:

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)]
Run Code Online (Sandbox Code Playgroud)

得到:

     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
Run Code Online (Sandbox Code Playgroud)

每@弗兰克的建议,你也可以做到这一点,而无需使用na.locf来自zoo-package:

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][]
Run Code Online (Sandbox Code Playgroud)