如何根据 R 中的 2 个日期时间变量合并行
How to merge rows based on 2 datetime variables in R
我想合并数据集 df
中的行,这样对于每个记录 ID,如果一行的 End_Date
等于下一行的 Start_Date
,然后我想把它们结合起来。
我目前的逻辑是先按 ID 分组,然后从第 1 行循环到第 n() 行。如果第 1 行的 End_Date
等于第 2 行的 Start_Date
,则将第 1 行的 End_Date
替换为第 2 行的 End_Date
并删除第 2 行。然后将第 1 行与新的第 2 行等等。
非常感谢有关如何为此编写代码的任何帮助或建议。谢谢!
df <- read.table(text = "
ID Start_Date End_Date
1 09/09/2016 11/09/2016
1 11/09/2016 17/09/2016
1 17/09/2016 23/11/2016
1 23/11/2016 28/11/2016
1 28/11/2016 14/12/2016
1 14/12/2016 22/12/2016
1 22/12/2016 23/12/2016
1 25/12/2016 03/01/2017
1 06/01/2017 07/02/2017
1 07/02/2017 22/02/2017
1 22/02/2017 27/02/2017
1 28/03/2017 30/05/2017
1 12/06/2017 03/07/2017
1 03/07/2017 04/07/2017
1 14/08/2017 14/08/2017
1 15/08/2017 23/08/2017
1 23/08/2017 24/08/2017
1 24/08/2017 28/08/2017
1 07/09/2017 07/09/2017
1 24/09/2017 24/09/2017
1 01/10/2017 08/11/2017
1 08/11/2017 31/12/2017
2 08/08/2017 10/08/2017
2 10/08/2017 11/08/2017", stringsAsFactors = FALSE, header = TRUE)
输出数据应如下所示:
df_new <- read.table(text = "
ID Start_Date End_Date
1 09/09/2016 23/12/2016
1 25/12/2016 03/01/2017
1 06/01/2017 27/02/2017
1 28/03/2017 30/05/2017
1 12/06/2017 04/07/2017
1 14/08/2017 14/08/2017
1 15/08/2017 28/08/2017
1 07/09/2017 07/09/2017
1 24/09/2017 24/09/2017
1 01/10/2017 31/12/2017
2 08/08/2017 11/08/2017", stringsAsFactors = FALSE, header = TRUE)
这是一个 dplyr 解决方案:
df %>%
mutate(collapse = Start_Date == lag(End_Date),
group = cumsum(c(0, tail(!collapse, -1)))) %>%
group_by(group) %>%
summarise(Start_Date = first(Start_Date),
End_Date = last(End_Date)) %>%
select(Start_Date, End_Date)
我鼓励您逐行运行检查发生了什么!
首先,它创建一个新列 collapse,如果一条记录的开始日期等于前一条记录的结束日期,则该列为真。因为第一行没有以前的记录,所以您将在第 1 行中得到一个 NA。
接下来,一个新的group列是通过对collapse列的累加求和来创建的,但是第一行的NA被修剪并替换为0。collapse需要被否定,因为我们只希望在遇到不应该合并的行时增加值。
最后,组列允许我们进行简单的分组和汇总。在这种情况下,我忽略了 ID 列。
(这还假设您的数据有序排列并且您不担心重叠的日期范围)。
我想合并数据集 df
中的行,这样对于每个记录 ID,如果一行的 End_Date
等于下一行的 Start_Date
,然后我想把它们结合起来。
我目前的逻辑是先按 ID 分组,然后从第 1 行循环到第 n() 行。如果第 1 行的 End_Date
等于第 2 行的 Start_Date
,则将第 1 行的 End_Date
替换为第 2 行的 End_Date
并删除第 2 行。然后将第 1 行与新的第 2 行等等。
非常感谢有关如何为此编写代码的任何帮助或建议。谢谢!
df <- read.table(text = "
ID Start_Date End_Date
1 09/09/2016 11/09/2016
1 11/09/2016 17/09/2016
1 17/09/2016 23/11/2016
1 23/11/2016 28/11/2016
1 28/11/2016 14/12/2016
1 14/12/2016 22/12/2016
1 22/12/2016 23/12/2016
1 25/12/2016 03/01/2017
1 06/01/2017 07/02/2017
1 07/02/2017 22/02/2017
1 22/02/2017 27/02/2017
1 28/03/2017 30/05/2017
1 12/06/2017 03/07/2017
1 03/07/2017 04/07/2017
1 14/08/2017 14/08/2017
1 15/08/2017 23/08/2017
1 23/08/2017 24/08/2017
1 24/08/2017 28/08/2017
1 07/09/2017 07/09/2017
1 24/09/2017 24/09/2017
1 01/10/2017 08/11/2017
1 08/11/2017 31/12/2017
2 08/08/2017 10/08/2017
2 10/08/2017 11/08/2017", stringsAsFactors = FALSE, header = TRUE)
输出数据应如下所示:
df_new <- read.table(text = "
ID Start_Date End_Date
1 09/09/2016 23/12/2016
1 25/12/2016 03/01/2017
1 06/01/2017 27/02/2017
1 28/03/2017 30/05/2017
1 12/06/2017 04/07/2017
1 14/08/2017 14/08/2017
1 15/08/2017 28/08/2017
1 07/09/2017 07/09/2017
1 24/09/2017 24/09/2017
1 01/10/2017 31/12/2017
2 08/08/2017 11/08/2017", stringsAsFactors = FALSE, header = TRUE)
这是一个 dplyr 解决方案:
df %>%
mutate(collapse = Start_Date == lag(End_Date),
group = cumsum(c(0, tail(!collapse, -1)))) %>%
group_by(group) %>%
summarise(Start_Date = first(Start_Date),
End_Date = last(End_Date)) %>%
select(Start_Date, End_Date)
我鼓励您逐行运行检查发生了什么!
首先,它创建一个新列 collapse,如果一条记录的开始日期等于前一条记录的结束日期,则该列为真。因为第一行没有以前的记录,所以您将在第 1 行中得到一个 NA。
接下来,一个新的group列是通过对collapse列的累加求和来创建的,但是第一行的NA被修剪并替换为0。collapse需要被否定,因为我们只希望在遇到不应该合并的行时增加值。
最后,组列允许我们进行简单的分组和汇总。在这种情况下,我忽略了 ID 列。
(这还假设您的数据有序排列并且您不担心重叠的日期范围)。