我有一个数据集,其中包含个人服务使用的开始和结束日期(每一集一行)。有时这些时期会重叠,有时则不会。我想计算一年中此人接触服务(使用 R)的唯一天数。尝试使用 IVS 包但遇到问题,因为这与开始日期和结束日期在同一天的行有关。我如何计算同一个人有单天服务以及多天服务的不同天数。
eg_data <- data.frame(
id = c(1,1,1, 2,2, 3,3,3,3,3,3, 4,4, 5,5,5,5),
start_dt = c("01/01/2016", "12/02/2016", "03/12/2017", "02/01/2016",
"03/04/2016", "01/01/2016", "03/05/2016", "05/07/2016", "07/01/2016",
"09/04/2016", "10/10/2016", "01/01/2016", "05/28/2016", "01/01/2016",
"06/05/2016", "08/25/2016", "11/01/2016"),
end_dt = c("12/01/2016", "12/02/2016", "05/15/2017", "05/15/2016",
"12/29/2016", "03/02/2016", "04/29/2016", "06/29/2016", "08/31/2016",
"03/04/2016", "11/29/2016", "05/31/2016", "08/19/2016", "06/10/2016",
"07/25/2016", "08/25/2016", "12/30/2016"))
eg_data$row_n <- 1:nrow(eg_data)
试过
ab <- a %>%
mutate(
start_dt = as.Date(ActivityStartDate, format = "%m/%d/%Y"),
end_dt = as.Date(ActivityEndDate, format = "%m/%d/%Y")
) %>%
mutate(
range = iv(start_dt, end_dt),
.keep = "unused"
)
c <-ab %>%
group_by(ID) %>%
mutate(group = iv_identify_group(range)) %>%
group_by(group, .add = TRUE)
但不适用于开始日期和结束日期在同一天的记录。还希望输出是一个带有日期变量的数据框,而不是一个向量,这样我就可以计算活动的总天数(不计算同一天不止一次)。
一种方法是过滤每个id的数据,获取并组合每一行的日期序列,然后统计唯一日期的数量。 不确定你需要输出作为带有日期变量的数据框是什么意思,但我将结果转换为数据框,希望它接近你所追求的。 请注意,在您的数据中,第 10 行的开始日期在结束日期之后,因此需要在以下内容起作用之前进行修复。我以为他们是从后到前。
DayTotals <- sapply(seq_along(unique(eg_data$id)), function(id_index) {
Current_id <- unique(eg_data$id)[id_index]
Current_id_data <- eg_data %>% filter(id == Current_id)
Current_id_dates <- apply(Current_id_data,1,function(row) {
seq.Date(from = as.Date(row['start_dt'],format="%m/%d/%Y"),
to=as.Date(row['end_dt'],format="%m/%d/%Y"),
by="day")})
Current_id_No_Of_Days <- Current_id_dates %>% unlist %>% unique %>% length
})
DayTotalsDF <- data.frame(id=unique(eg_data$id),
NoOfDays=DayTotals)
> DayTotalsDF
id NoOfDays
1 1 402
2 2 333
3 3 298
4 4 232
5 5 268
library(lubridate)
library(dplyr)
library(purrr)
eg_data <- data.frame(
id = c(1, 2, 3),
start_date = c("2022-01-01", "2022-03-05", "2022-04-12"),
end_date = c("2022-01-05", "2022-03-10", "2022-04-16")
)
eg_data$start_dt <- ymd(eg_data$start_date)
eg_data$end_dt <- ymd(eg_data$end_date)
eg_data %>%
mutate(
date_list = map2(start_dt, end_dt, seq, by = "day"),
date = map(date_list, ~ paste0(format(.x, "%Y-%m-%d"), collapse = ", "))
) %>%
select(id, date)
上面的代码采用一个包含开始日期和结束日期列的数据框,并创建一个新的数据框,其中包含这些开始日期和结束日期之间的每日日期。下面是代码的详细解释:
第一行代码加载lubridate和dplyr包,程序中用到了。 lubridate 包提供了处理日期和时间的工具,而 dplyr 用于数据操作。
下一行代码创建了一个名为 eg_data 的示例数据框,其中包含两列,名为 start_dt 和 end_dt。这些列包含日期值,并代表每个期间的开始和结束日期。
dplyr 包中的 mutate() 函数用于在 eg_data 数据框中创建一个名为 date_list 的新列。此列是使用 purrr 包中的 map2() 函数创建的。 map2() 接受三个参数:开始日期、结束日期和应用于每对开始日期和结束日期的函数。在这种情况下,seq() 函数应用于每对开始日期和结束日期,以生成这两个值之间的日期序列。
seq() 函数生成开始日期和结束日期之间的日期序列,使用“天”作为步长。这将创建一个向量列表,其中每个向量包含给定开始日期和结束日期之间的每日日期。
tidyr 包中的 unnest() 函数用于解除向量列表的嵌套,以便每个每日日期值出现在 eg_data 数据框中的单独行中。
最后,dplyr 的 select() 函数用于仅选择最终输出中需要的列:start_dt、end_dt 和 date_list。 distinct() 函数用于删除输出中的任何重复行。
您可以尝试此代码,如果需要更多帮助,请关注我的博客
使用 difftime() 计算开始日期和结束日期之间的天数,并加 1 以包括开始日期和结束日期。然后按 ID 对数据进行分组,并对有活动的天数求和。
参见:https://www.mycompiler.io/view/AAAyWCmzw0X
library(dplyr)
eg_data <- data.frame(
id = c(1,1,1, 2,2, 3,3,3,3,3,3, 4,4, 5,5,5,5),
start_dt = c("01/01/2016", "12/02/2016", "03/12/2017", "02/01/2016",
"03/04/2016", "01/01/2016", "03/05/2016", "05/07/2016", "07/01/2016",
"09/04/2016", "10/10/2016", "01/01/2016", "05/28/2016", "01/01/2016",
"06/05/2016", "08/25/2016", "11/01/2016"),
end_dt = c("12/01/2016", "12/02/2016", "05/15/2017", "05/15/2016",
"12/29/2016", "03/02/2016", "04/29/2016", "06/29/2016", "08/31/2016",
"03/04/2016", "11/29/2016", "05/31/2016", "08/19/2016", "06/10/2016",
"07/25/2016", "08/25/2016", "12/30/2016"))
eg_data$row_n <- 1:nrow(eg_data)
eg_data %>%
mutate(
start_dt = as.Date(start_dt, format = "%m/%d/%Y"),
end_dt = as.Date(end_dt, format = "%m/%d/%Y"),
min_date = pmin(start_dt, end_dt),
max_date = pmax(start_dt, end_dt),
n_days = as.numeric(difftime(max_date, min_date, units = "days")) + 1
) %>%
group_by(id) %>%
summarize(total_days = sum(n_days))
结果是;
id total_days
<dbl> <dbl>
1 1 402
2 2 406
3 3 470
4 4 236
5 5 274
如果这不是想要的结果,请提供想要的结果,如果可能的话,请解释你是如何得到的(仅来自示例数据)