下面的代码生成一个模拟数据集:
library(lubridate)
library(tibble)
example_data = tibble(
ID = c(1, 2, 3),
Gender = c("Male", "Female", "Female"),
Age = c(18, 28, 38),
Time_Period = c(
interval(as.Date(now()), as.Date(now() + months(3) + days(10))),
interval(as.Date(now() + months(1)), as.Date(now() + months(4) + days(13))),
interval(as.Date(now() + months(2)), as.Date(now() + months(8) + days(4)))
)
)具有以下输出
ID Gender Age Time_Period
<dbl> <chr> <dbl> <Interval>
1 1 Male 18 2022-11-10 UTC--2023-02-20 UTC
2 2 Female 28 2022-12-10 UTC--2023-03-23 UTC
3 3 Female 38 2023-01-10 UTC--2023-07-14 UTC每个ID的Time_Period变量覆盖一定数量的月。
例如,第一行包含3个月零10天的间隔。对于ID = 1,我希望一个新的数据集包含四行,新的间隔列的长度为一个月,最后一个数据集一直持续到原始间隔的结束点。
这将对所有ID重复。
数据集如下所示,下一行间隔开始日期从上一行开始日期后一个月开始(插入用于可读性的空格):
ID Gender Age Split_Up_Intervals
<dbl> <chr> <dbl> <Interval>
1 Male 18 2022-11-10 UTC--2022-12-09 UTC
1 Male 18 2022-12-10 UTC--2023-01-09 UTC
1 Male 18 2023-01-10 UTC--2023-02-09 UTC
1 Male 18 2023-02-10 UTC--2023-02-20 UTC
2 Female 28 2022-12-10 UTC--2023-01-09 UTC
2 Female 28 2023-01-10 UTC--2023-02-09 UTC
2 Female 28 2023-02-10 UTC--2023-03-09 UTC
2 Female 28 2023-03-10 UTC--2023-03-23 UTC
3 Female 38 2023-01-10 UTC--2023-02-09 UTC
3 Female 38 2023-02-10 UTC--2023-03-09 UTC
3 Female 38 2023-03-10 UTC--2023-04-09 UTC
3 Female 38 2023-04-10 UTC--2023-05-09 UTC
3 Female 38 2023-05-10 UTC--2023-06-09 UTC
3 Female 38 2023-06-10 UTC--2023-07-09 UTC
3 Female 38 2023-07-10 UTC--2023-07-14 UTC我认为这可以使用类似于这里(创建“每天”行,使用tidyverse从选择性的“每月”数字创建)的东西来完成,但我不能完全让它工作。而且,我将使用的实际数据集有大量列,因此我希望在每一行中复制所有其他变量。
发布于 2022-11-10 09:34:59
这是你想做的事情。其思想是,对于每个间隔,我们需要创建一个列,列包含由区间定义的序列(即,如果间隔覆盖4.5个月,则有五个月间隔)。
ex2=data.frame(ID=c(1,2,3), x = c('a','b','c'), n=c(5,6,3))现在,对于任何特定的行,我们可以使用merge来追加包含可变长度序列的列,让我们使用n列中的值来定义序列的长度:
merge(ex2[1,],
data.frame(s=seq(1,ex2[1,]$n))) Id x n s
1 1 a 5 1
2 1 a 5 2
3 1 a 5 3
4 1 a 5 4
5 1 a 5 5现在,以某种方式将其绑定到数据帧的每一行,并绑定输出数据帧。我想你可以用将数据帧的每一行转换为列表做这个,然后用lapply
res=lapply(split(ex2,seq(nrow(ex2))),
FUN=function(x) merge(x, data.frame(s=seq(x$n))))$`1`
Id x n s
1 1 a 5 1
2 1 a 5 2
3 1 a 5 3
4 1 a 5 4
5 1 a 5 5
$`2`
Id x n s
1 2 b 6 1
2 2 b 6 2
3 2 b 6 3
4 2 b 6 4
5 2 b 6 5
6 2 b 6 6
$`3`
Id x n s
1 3 c 3 1
2 3 c 3 2
3 3 c 3 3现在使用dplyr::bind_rows和do.call组合数据帧:
library(dplyr)
do.call('bind_rows', res)我们可以对您的示例数据应用相同的想法。我们不使用n来定义序列的长度,而是创建一个从间隔开始的序列,步骤大小为一个月,其长度是间隔中的月数(或其中的一部分):
do.call("bind_rows",
lapply(split(example_data,seq(nrow(example_data))),
FUN=function(x) merge(x,
data.frame(start_date=seq(from=int_start(x$Time_Period),
by=duration(1, 'months'),
length.out=ceiling(x$Time_Period/duration(1, 'months'))))))) ID Gender Age Time_Period start_date
1 1 Male 18 2022-11-10 UTC--2023-02-20 UTC 2022-11-10 00:00:00
2 1 Male 18 2022-11-10 UTC--2023-02-20 UTC 2022-12-10 10:30:00
3 1 Male 18 2022-11-10 UTC--2023-02-20 UTC 2023-01-09 21:00:00
4 1 Male 18 2022-11-10 UTC--2023-02-20 UTC 2023-02-09 07:30:00
5 2 Female 28 2022-12-10 UTC--2023-03-23 UTC 2022-12-10 00:00:00
6 2 Female 28 2022-12-10 UTC--2023-03-23 UTC 2023-01-09 10:30:00
7 2 Female 28 2022-12-10 UTC--2023-03-23 UTC 2023-02-08 21:00:00
8 2 Female 28 2022-12-10 UTC--2023-03-23 UTC 2023-03-11 07:30:00
9 3 Female 38 2023-01-10 UTC--2023-07-14 UTC 2023-01-10 00:00:00
10 3 Female 38 2023-01-10 UTC--2023-07-14 UTC 2023-02-09 10:30:00
11 3 Female 38 2023-01-10 UTC--2023-07-14 UTC 2023-03-11 21:00:00
12 3 Female 38 2023-01-10 UTC--2023-07-14 UTC 2023-04-11 07:30:00
13 3 Female 38 2023-01-10 UTC--2023-07-14 UTC 2023-05-11 18:00:00
14 3 Female 38 2023-01-10 UTC--2023-07-14 UTC 2023-06-11 04:30:00
15 3 Female 38 2023-01-10 UTC--2023-07-14 UTC 2023-07-11 15:00:00我对lubridate还不太了解,不能在这里继续(开始日期不是一个月,您需要正确地设置结束日期,并创建一个间隔),但希望这会有所帮助。
https://stackoverflow.com/questions/74384337
复制相似问题