我有一个看起来像这样的数据框:
ID Group Start Date End Date
1 A 2018-08-08 2018-08-09
1 A 2018-08-07 2018-08-08
1 A 2018-08-05 2018-08-07
1 B 2018-08-08 2018-08-09
1 B 2018-08-07 2018-08-08
2 A 2018-08-08 2018-08-09
2 A 2018-08-07 2018-08-08
2 A 2018-08-01 2018-08-07
2 B 2018-08-08 2018-08-09
2 B 2018-08-07 2018-08-08
3 B 2018-08-07 2018-08-08
4 B 2018-08-07 2018-08-08
4 B 2018-08-01 2018-08-07
我想折叠它,以便如果一行中的Start Date
变量与下一行中的End Date
变量相匹配,则这些行将按ID
和Group
个变量:
ID Group Start Date End Date
1 A 2018-08-05 2018-08-09
1 B 2018-08-07 2018-08-09
2 A 2018-08-01 2018-08-09
2 B 2018-08-07 2018-08-09
3 B 2018-08-07 2018-08-08
4 B 2018-08-01 2018-08-08
在dplyr中,我知道可以通过类似以下操作来做到这一点:
df %>%
group_by(ID, Group) %>%
rowwise() %>%
do(somefunction(x){})
但是我在编写函数时需要帮助。或者,如果有一个for循环或其他实现可以做到这一点,将不胜感激。
修改 为了更清楚起见,我已经修改了示例数据。
答案 0 :(得分:-1)
我已经使用BioConducter的IRanges
软件包找到了更灵活的解决方案。这对于不一定与邻居连续的情况非常有效:
source("http://bioconductor.org/biocLite.R")
biocLite("IRanges")
require(IRanges)
library(data.table)
library(lubridate)
setDT(df)
df[, , as.data.table(reduce(
IRanges(as.numeric(`Start Date`),
as.numeric(`End Date`)),
min.gapwidth=1L))[, lapply(.SD, as_date), .SDcols = -"width"],
.(`ID`, `Group`)]
在上面的代码段中,我在每个日期范围内使用了reduce
中的IRanges
函数,该函数会将给定容差min.gapwidth
中的相邻范围折叠起来。在这种情况下,我指定了日期范围(如果彼此之间在一天之内)(min.gapwidth=1L
)。您可以将其设置为0L
以合并严格连续的日期。
IRanges
仅采用数字值,因此我将日期转换为数字,然后应用as_date
包中的lubridate
函数将其转换回日期。我还删除了width
列,该列将告诉我每个范围内有多少天。