我正在处理 R 中的大型数据集,包含大约 1900 万行和超过 81 列,我需要一些关于有效处理它的指导。
我的数据集按名称(实际上是另一个 ID,但为了简单起见,我们在这里说名称)跟踪重复出现的记录,以及它们的值、开始和结束日期,其中一些记录在几年后已被取消。这是我的数据结构的简化示例:
名字 | 价值 | 取消了 | 开始 | 结束 |
---|---|---|---|---|
ABC | 77 | 2010 | 2011 | |
ABC | 66 | 2010 | 2011 | |
ABC | 55 | 2010 | 2011 | |
ABC | 44 | 2011 | 2012 | |
ABC | 33 | 2012 | 2011 | 2012 |
ABC | 22 | 2011 | 2012 | |
ABC | 11 | 2012 | 2013 | |
ABC | 44 | 2012 | 2013 | |
咩咩 | 33 | 2009 | 2012 | |
咩咩 | 22 | 2009 | 2010 | |
咩咩 | 45 | 2009 | 2010 | |
咩咩 | 23 | 2011 | 2009 | 2011 |
咩咩 | 54 | 2010 | 2011 | |
咩咩 | 15 | 2012 | 2013 | |
咩咩 | 42 | 2010 | 2011 | |
ABC | 16 | 2013 | 2014 | |
ABC | 10 | 2013 | 2014 |
我的目标是为每个相关记录序列分配一个唯一的 ID,其中序列由共享相同名称的连续记录定义。我的基本理解是,如果行没有取消日期,则将名称 ABC 的第 1 行与 ABC 的下一个出现的第 2 行匹配,其中第 1 行的结束日期与第 2 行的开始日期匹配。如果记录被取消,它不应该链接到同名的后续出现。例如,期望的结果如下所示:
名字 | 价值 | 取消了 | 开始 | 结束 | new_unique_id |
---|---|---|---|---|---|
ABC | 77 | 2010 | 2011 | 1 | |
ABC | 44 | 2011 | 2012 | 1 | |
ABC | 11 | 2012 | 2013 | 1 | |
ABC | 16 | 2013 | 2014 | 1 | |
ABC | 66 | 2010 | 2011 | 2 | |
ABC | 33 | 2012 | 2011 | 2012 | 2 |
ABC | 55 | 2010 | 2011 | 3 | |
ABC | 22 | 2011 | 2012 | 3 | |
ABC | 44 | 2012 | 2013 | 3 | |
ABC | 10 | 2013 | 2014 | 3 | |
咩咩 | 33 | 2009 | 2012 | 4 | |
咩咩 | 15 | 2012 | 2013 | 4 | |
咩咩 | 22 | 2009 | 2010 | 5 | |
咩咩 | 54 | 2010 | 2011 | 5 | |
咩咩 | 45 | 2009 | 2010 | 6 | |
咩咩 | 42 | 2010 | 2011 | 6 | |
咩咩 | 23 | 2011 | 2009 | 2011 | 7 |
考虑到我的数据集的规模(3GB FST & 17 Mio & 81 列),在 R 中使用传统循环被证明是低效的。我正在寻找一种利用矢量化操作或 dplyr(或您能想到的任何其他)函数来更有效地完成此任务的方法。
任何有关如何解决此问题的见解或建议将不胜感激!
你可以用这个
df$semi_id <- c(FALSE,
df$start[2:(nrow(df))] < df$start[1:(nrow(df)-1)] |
df$name[2:(nrow(df))] != df$name[1:(nrow(df)-1)])
df$new_unique_id <- 1+ cumsum(df$semi_id)
请提供您的数据,而不是表格,而是这样:
df <- data.frame(name= c(rep("ABC", 10), rep("BAA", 7)),
cancelled= c(rep(NA, 5), 2012, rep(NA, 10), 2011),
start= c(2010:2013, 2010:2011, 2010:2013, 2009, 2012, 2009:2010, 2009:2010, 2009))