合并非关键变量的所有“出现”

Posted

技术标签:

【中文标题】合并非关键变量的所有“出现”【英文标题】:Merge for all "occurrences" of a non-key variable 【发布时间】:2018-06-02 17:48:00 【问题描述】:

我有两个数据集,我想要的可能被松散地称为“非键变量的外部连接”。

这里是数据集

数据集 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 解决方案也可以。

【问题讨论】:

【参考方案1】:

使用:

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 的建议,您也可以不使用zoo-package 中的na.locf

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][]

【讨论】:

谢谢,你已经实现了我在几秒钟内想到的“过程”。我从来不知道CJon。我在哪里可以了解它们? 另外,on = .(oc, state_id) 给我抛出一个错误。我不得不使用on = c('oc', 'state_id')。可能是我有旧版本的data.table @GauravSinghal 我正在使用版本 1.10.4-3;你用的是什么版本? 是的,我使用的是 1.9.6 版本。 @Frank 谢谢!添加了一个小改动:我认为最后一次加入应该在state_id【参考方案2】:

这可以表示为使用三联连接的单个 SQL 语句,该三联连接将这 4 个表连接在一起:

oc 由唯一的 oc 值组成, state_id 由唯一的 state_id 值组成, DT1DT2

使用此代码:

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

【讨论】:

以上是关于合并非关键变量的所有“出现”的主要内容,如果未能解决你的问题,请参考以下文章

合并重复行并设置值

如何合并存储在python变量中的多个路径中的所有文件?

makefile中的特殊符号及关键字

C语言关键字 - 铁布衫:const 转载

51Nod1782 圣诞树

尽管对所有关键变量进行了分组,SQL 还是重复?