R 如何从更改的数据帧创建查找表?

R 如何从更改的数据帧创建查找表?,r,dataframe,dplyr,tidyverse,lookup-tables,R,Dataframe,Dplyr,Tidyverse,Lookup Tables,我想从变更的数据帧创建一个查找表。原始数据帧的每一行表示给定地区编码的变化。该数据集涵盖2009年至2019年的一段时间。虽然一个地区在这段时间内可能会经历几次变化,但我想要每个地区的2009年和2019年编码。即,第一个和最新的编码 数据框架覆盖了数百个地区。一些地区可能只经历一次变革,而其他地区则经历多次变革。一个地区可以合并或拆分为多个其他地区 理想的查找表如下所示: 编码(2009) 编码单元2019 00QR S12000047 00QR S12000048 00RB S1200004

我想从变更的数据帧创建一个查找表。原始数据帧的每一行表示给定地区编码的变化。该数据集涵盖2009年至2019年的一段时间。虽然一个地区在这段时间内可能会经历几次变化,但我想要每个地区的2009年和2019年编码。即,第一个和最新的编码

数据框架覆盖了数百个地区。一些地区可能只经历一次变革,而其他地区则经历多次变革。一个地区可以合并或拆分为多个其他地区

理想的查找表如下所示:

编码(2009) 编码单元2019 00QR S12000047 00QR S12000048 00RB S12000047 00RB S12000048
您实际上看到的是一个扁平的树结构。使用IGRAPHE软件包可以轻松绘制图形:

图书馆记录仪 g%选择过去、新%>%t%>%c%>%graph 图g 从现在开始,有很多方法可以解决这个问题,但可以归结为深度优先或宽度优先的方法来解决这个问题

假设我们有几个小图是合理的。一组经过一些更改的不同代码,而不是经过多次更改的精选代码

这表明了一种宽度优先的方法,并且可以通过将数据连接到自身来解决,希望不会太多次:

使用data.table获得额外的速度。 setDTdat 删除相同代码的重复项 datSirius使用data.table提供了一个惊人的答案。在这里,我将这个答案翻译成tidyverse:


太神了使用igraph也很酷。第一次尝试效果很好-我明天再尝试。非常感谢你的帮助!

> dd[ order(past), .(coding_2009=past,coding_2019=new) ]
    coding_2009 coding_2019
 1:        00HC   E06000024
 2:        00KG   E06000034
 3:        00QR   S12000047
 4:        00QR   S12000048
 5:        00RB   S12000047
 6:        00RB   S12000048
 7:        00RJ   S12000013
 8:        13UD   E06000049
 9:        15UH   E06000053
10:        19UD   E06000059
11:        19UE   E06000059
12:        19UG   E06000059
13:        19UH   E06000059
14:        19UJ   E06000059
15:   E07000014   E06000049
16:   E07000017   E06000049

# Remove duplicate entries of same code
data_sub <- data %>%
  group_by(past, new) %>%
  filter(date == max(date)) %>%
  ungroup()

# Create roots: All past values never present in new
roots <- data_sub %>%
  filter(!past %in% new)

# Create leaves: Those that never appear as past, unless they self reference
leaves <- data_sub %>%
  filter(!new %in% past | new == past) %>%
  select(-past) %>%
  distinct(new, .keep_all = TRUE)

# Copy before loop
dd <- roots

# Successively add next step from source data until we have arrived at leaves only
while(!all(dd$new %in% leaves$new)) {
  
  # Join
  dd_merge <- left_join(dd, data_sub, by = c("new" = "past"))
  
  # Coalesce
  dd_sub <- dd_merge %>%
    transmute(date.x,
              past,
              new = coalesce(new.y, new),
              date.y = coalesce(date.y, date.x))
  
  # Take unique
  dd <- unique(dd_sub)
  
}