以预定义长度R的间隔分割数据

vngu2lb8  于 2023-04-27  发布在  其他
关注(0)|答案(2)|浏览(90)

我在下面的表格上有一个数据集:
| 身份证|开始日期|结束日期|
| --------------|--------------|--------------|
| 1|2020-01-01 2020-01-01|2021-01-01 2021- 01-01|
| 二|2000-03-02|2021-01-01 2021- 01-01|
我想在90天的间隔从开始到结束日期分裂。我也许可以找到一个工作,但由于我需要执行多次,我正在寻找一个相对简单的代码。我想do.call可能是要走的路?
如果结束间隔不适合90天的周期,则最后间隔可以小于90天。
| 身份证|开始日期|结束日期|
| --------------|--------------|--------------|
| 1|2020-01-01 2020-01-01|2020-03-31 2020-03-31|
| 1|2020-03-31 2020-03-31|2020-06-29 2020-06-29 2020-06-29|
| ……|||
| 二|2000-03-02|2000-05-31|

jc3wubiy

jc3wubiy1#

我们可以创建一个小的helper来扩展一个start/end对,并在dplyr::reframe()中使用它。你必须在你的数据上逐行运行这个,所以如果你有很多行,它会有点慢,但我不确定是否有其他方法可以做到这一点。

library(dplyr, warn.conflicts = FALSE)
library(rlang)

df <- tibble(
  id = c(1L, 2L),
  start = as.Date(c("2020-01-01", "2000-03-02")),
  end = as.Date(c("2021-01-01", "2021-01-01"))
)

expand <- function(from, to) {
  # Generate sequence by 90 days, ensuring `to` is retained
  x <- seq(from, to, by = 90)
  x <- unique(c(x, to))
  
  # Safely diff the sequence into start/end
  size <- length(x)
  start <- seq2(1L, size - 1L)
  end <- seq2(2L, size)
  start <- x[start]
  end <- x[end]
  
  # Return in a data frame that `reframe()` can unpack
  data.frame(start = start, end = end)
}

df %>%
  reframe(expand(start, end), .by = id)
#> # A tibble: 90 × 3
#>       id start      end       
#>    <int> <date>     <date>    
#>  1     1 2020-01-01 2020-03-31
#>  2     1 2020-03-31 2020-06-29
#>  3     1 2020-06-29 2020-09-27
#>  4     1 2020-09-27 2020-12-26
#>  5     1 2020-12-26 2021-01-01
#>  6     2 2000-03-02 2000-05-31
#>  7     2 2000-05-31 2000-08-29
#>  8     2 2000-08-29 2000-11-27
#>  9     2 2000-11-27 2001-02-25
#> 10     2 2001-02-25 2001-05-26
#> # ℹ 80 more rows
efzxgjgh

efzxgjgh2#

另一种方法可能是使用seqstartend 90天,对于每个id,保留end列。然后,将end列修改为endstart的90天之间的较早日期,以防止超过结束日期。

library(tidyverse)

df %>%
  reframe(end, start = seq.Date(start, end, "90 days"), .by = id) %>%
  mutate(end = pmin(end, start + 90), .by = id) %>%
  relocate(end, .after = start)

输出

id start      end       
   <int> <date>     <date>    
 1     1 2020-01-01 2020-03-31
 2     1 2020-03-31 2020-06-29
 3     1 2020-06-29 2020-09-27
 4     1 2020-09-27 2020-12-26
 5     1 2020-12-26 2021-01-01
 6     2 2000-03-02 2000-05-31
 7     2 2000-05-31 2000-08-29
 8     2 2000-08-29 2000-11-27
 9     2 2000-11-27 2001-02-25
10     2 2001-02-25 2001-05-26
# ℹ 80 more rows
# ℹ Use `print(n = ...)` to see more rows

相关问题