我有一个带有ID、Start_date和End_date字段的数据集。此数据集中的某些记录的结束日期与相同ID的开始日期匹配,但位于不同的行中。例如,一个ID的日期可以是2002-01-20到2002-01-22,而另一个记录的日期可以是2002-01-22到2002-01-23。我希望将这些记录合并在一起,这样我就只有一条ID的记录,该记录的开始日期是第一条记录(2002-01-20),结束日期是第二条记录(2002-01-23)。
原始数据示例:
structure(list(ID = c(565, 898, 521, 522, 522, 323, 887, 887,
522), Start_date = structure(c(12846, 19172, 19341, 19495, 19497,
19495, 14194, 14204, 18786), class = "Date"), End_date = structure(c(12847,
19174, 19347, 19497, 19499, 19497, 14203, 14206, 18798), class = "Date")), row.names = c(NA,
-9L), class = c("tbl_df", "tbl", "data.frame"))
示例最终数据:
structure(list(ID = c(565, 898, 521, 522, 323, 887, 887, 522),
Start_date = structure(c(12846, 19172, 19341, 19495, 19495,
14194, 14204, 18786), class = "Date"), End_date = structure(c(12847,
19174, 19347, 19499, 19497, 14203, 14206, 18798), class = "Date")), row.names = c(NA,
-8L), class = c("tbl_df", "tbl", "data.frame"))
对于这个问题,似乎有很多关于stackoverflow的SQL解决方案,但是我无法使用R找到一个。谢谢你。
3条答案
按热度按时间wmomyfyw1#
首先,我们可以使用
inner_join
将数据集连接到自身,并只保留具有相同ID和匹配的开始/结束日期的行:我们重命名列以仅保留正确的End_date:
然后我们执行相同的操作,使用
anti_join
删除这些行。因为我们要删除两行(一行是开始日期,另一行是结束日期),所以我们需要执行两次:我们完成了,我们可以把这两个结合起来:
ijxebb2r2#
如何运作
1.在
ID
(例如.by = ID
)中,我们找到End_date
也是另一行中Start_date
的行。1.当满足该条件时,在
ID
内,对于该行,我们将End_date
设置为最大日期。max date返回最近的按时间顺序排列的日期。当此操作完成后,End_date
现在将为给定的ID
复制到两行中。1.最后,我们可以简单地使用
distinct
删除该行,这将保留第一行在ID
和End_date
中的唯一值。注意:
.by
是实验性的,从packageVersion("dplyr")
1.1.0开始是新的。如果您使用的是旧版本的dplyr
,则可以执行以下操作:输出
一个警告是以下场景,其中
ID
中有匹配的Start_date
和End_date
,但有一个额外的不匹配行,其日期更近(第三行):然后,您可以执行以下操作:
xqnpmsa83#
我最终使用以下代码解决了这个问题,这说明了我的数据中的一些细微差别,包括(1)希望保留与记录相关的原始数据集中的其他变量(2)能够说明可能有3或4个记录的情况,我希望链接在一起;以及(3)ID可以并且确实在我的数据集中重复的事实,一些我希望合并,而另一些我希望保持分离,因为它们不符合我的标准(相同的结束/开始日期)。