填补R中咒语之前、之间和之后(日期范围)的空白

填补R中咒语之前、之间和之后(日期范围)的空白,r,data.table,tidyverse,tidyr,R,Data.table,Tidyverse,Tidyr,假设您有一个由三名研究参与者组成的数据框架,其中包括他们的进入日期(doe)和退出日期(dox): >参与者 身份证 1 1 1990/01/04 2020/01/02 2 2 1988/05/02 1999/03/01 3 3 2001/06/04 2011/05/06 在doe和dox之间的不同时间段,他们三人都接受过寄养: > placement_dates<-data.frame( + id = c(1L, 1L, 1L, 1L, 1L, 1L,

假设您有一个由三名研究参与者组成的数据框架,其中包括他们的进入日期(doe)和退出日期(dox):

>参与者
身份证
1  1 1990/01/04 2020/01/02
2  2 1988/05/02 1999/03/01
3  3 2001/06/04 2011/05/06
在doe和dox之间的不同时间段,他们三人都接受过寄养:

> placement_dates<-data.frame(
+           id = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L),
+           placement_start = c("1993/04/21","1994/12/04","1994/12/19",
+                  "2000/01/14","2003/11/22","2015/03/03","1993/04/21",
+                  "1993/05/13","1998/02/19","2005/01/31"),
+           placement_end = c("1993/06/01","1994/12/06","1995/05/02",
+                  "2002/12/04","2005/06/01","2019/02/08","1993/05/12",
+                  "1996/01/30","1998/02/28","2006/08/19")
+ )
> placement_dates
   id placement_start placement_end
1   1      1993/04/21    1993/06/01
2   1      1994/12/04    1994/12/06
3   1      1994/12/19    1995/05/02
4   1      2000/01/14    2002/12/04
5   1      2003/11/22    2005/06/01
6   1      2015/03/03    2019/02/08
7   2      1993/04/21    1993/05/12
8   2      1993/05/13    1996/01/30
9   2      1998/02/19    1998/02/28
10  3      2005/01/31    2006/08/19
>放置日期放置日期
id放置\开始放置\结束
1   1      1993/04/21    1993/06/01
2   1      1994/12/04    1994/12/06
3   1      1994/12/19    1995/05/02
4   1      2000/01/14    2002/12/04
5   1      2003/11/22    2005/06/01
6   1      2015/03/03    2019/02/08
7   2      1993/04/21    1993/05/12
8   2      1993/05/13    1996/01/30
9   2      1998/02/19    1998/02/28
10  3      2005/01/31    2006/08/19
我现在感兴趣的是将参与者和安置日期数据框结合起来,生成不被安置在寄养机构(拼写类型=A)和被安置在寄养机构(拼写类型=B)的拼写。因此,我期望的结果是:

> desired_df <- data.frame(
+   id = c(1L,1L,1L,1L,1L,1L,1L,1L,
+          1L,1L,1L,1L,1L,2L,2L,2L,2L,2L,2L,3L,3L,3L),
+   spell_start = c("1990/01/04","1993/04/21",
+          "1993/06/02","1994/12/04","1994/12/07","1994/12/19",
+          "1995/05/03","2000/01/14","2002/12/05","2003/11/22",
+          "2005/06/02","2015/03/03","2019/02/09","1988/05/02",
+          "1993/04/22","1993/05/13","1996/01/31","1998/02/19",
+          "1998/03/01","2001/06/04","2005/01/31","2006/08/20"),
+   spell_end = c("1993/04/20","1993/06/01",
+          "1994/12/03","1994/12/06","1994/12/18","1995/05/02",
+          "2000/01/13","2002/12/04","2003/11/21","2005/06/01",
+          "2015/03/02","2019/02/08","2020/01/02","1993/04/21",
+          "1993/05/12","1996/01/30","1998/02/18","1998/02/28",
+          "1999/03/01","2005/01/30","2006/08/19","2011/05/06"),
+   spell_type = c("A","B","A","B","A","B",
+          "A","B","A","B","A","B","A","A","B","B","A","B",
+          "A","A","B","A")
+ )
> desired_df
   id spell_start  spell_end spell_type
1   1  1990/01/04 1993/04/20          A
2   1  1993/04/21 1993/06/01          B
3   1  1993/06/02 1994/12/03          A
4   1  1994/12/04 1994/12/06          B
5   1  1994/12/07 1994/12/18          A
6   1  1994/12/19 1995/05/02          B
7   1  1995/05/03 2000/01/13          A
8   1  2000/01/14 2002/12/04          B
9   1  2002/12/05 2003/11/21          A
10  1  2003/11/22 2005/06/01          B
11  1  2005/06/02 2015/03/02          A
12  1  2015/03/03 2019/02/08          B
13  1  2019/02/09 2020/01/02          A
14  2  1988/05/02 1993/04/21          A
15  2  1993/04/22 1993/05/12          B
16  2  1993/05/13 1996/01/30          B
17  2  1996/01/31 1998/02/18          A
18  2  1998/02/19 1998/02/28          B
19  2  1998/03/01 1999/03/01          A
20  3  2001/06/04 2005/01/30          A
21  3  2005/01/31 2006/08/19          B
22  3  2006/08/20 2011/05/06          A
>需要的\u-df需要的\u-df
id拼写\u开始拼写\u结束拼写\u类型
1 1990/01/04 1993/04/20 A
2 1 1993/04/21 1993/06/01 B
3 1 1993/06/02 1994/12/03 A
411994/12/041994/12/06B
511994/12/071994/12/18A
611994/12/191995/05/02B
711995/05/032000/01/13A
8 1 2000/01/14 2002/12/04 B
9.1 2002/12/05 2003/11/21 A
10 1 2003/11/22 2005/06/01 B
11.1 2005/06/02 2015/03/02 A
12.1 2015/03/03 2019/02/08 B
13 1 2019/02/09 2020/01/02 A
1421988/05/021993/04/21A
1521993/04/221993/05/12B
1621993/05/131996/01/30B
1721996/01/31998/02/18A
1821998/02/191998/02/28B
1921998/03/01 1999/03/01 A
20 3 2001/06/04 2005/01/30 A
21 3 2005/01/31 2006/08/19 B
22 3 2006/08/20 2011/05/06 A

我的实际数据集有大约30万个寄养安置,有不同类型的安排。因此,spell_类型变量更复杂,但我需要一些想法来开始。我已经研究了tidyr软件包中的完整功能,但我无法针对我的具体问题实现它。

这里有一个
数据。表
选项:

#calculate spell_start
ans <- placement_dates[participants, on=.(id), by=.EACHI,
    .(spell_start=sort(unique(c(doe, placement_start, placement_end+1L))))]

#calculate and populate spell_end
ans[, spell_end := shift(spell_start, -1L) - 1L, id]
ans[is.na(spell_end), spell_end := participants[.SD, on=.(id), dox]]

#populate spell_type
ans[, spell_type := "NotInFoster"][
    placement_dates, on=.(id, spell_start=placement_start, spell_end=placement_end), 
    spell_type := "InFoster"]
数据:

库(data.table)

参与者生成
拼写类型
的参数是什么?在这个特定的玩具示例中,它只是参与者是否处于寄养状态的一个二进制指示器。如果特定的咒语包含在
placement\u dates
中,则
咒语类型始终为“B”,否则为“A”。感谢您的解决方案,但您的输出与我想要的输出不匹配。例如,比较第15行和第16行。魔咒末代出了点问题,我想不出来。太好了,谢谢!我无法在计算服务器上复制结果,但结果表明它们使用的是
data.table
(v1.11.4)的过时版本,因此解决方案的shift()部分不起作用。不过,上面的玩具示例在我的笔记本电脑上运行得非常好。对于较旧版本的
data.table
,您可以使用
shift(拼写开始,1L,type=“lead”)
#calculate spell_start
ans <- placement_dates[participants, on=.(id), by=.EACHI,
    .(spell_start=sort(unique(c(doe, placement_start, placement_end+1L))))]

#calculate and populate spell_end
ans[, spell_end := shift(spell_start, -1L) - 1L, id]
ans[is.na(spell_end), spell_end := participants[.SD, on=.(id), dox]]

#populate spell_type
ans[, spell_type := "NotInFoster"][
    placement_dates, on=.(id, spell_start=placement_start, spell_end=placement_end), 
    spell_type := "InFoster"]
    id spell_start  spell_end  spell_type
 1:  1  1990-01-04 1993-04-20 NotInFoster
 2:  1  1993-04-21 1993-06-01    InFoster
 3:  1  1993-06-02 1994-12-03 NotInFoster
 4:  1  1994-12-04 1994-12-06    InFoster
 5:  1  1994-12-07 1994-12-18 NotInFoster
 6:  1  1994-12-19 1995-05-02    InFoster
 7:  1  1995-05-03 2000-01-13 NotInFoster
 8:  1  2000-01-14 2002-12-04    InFoster
 9:  1  2002-12-05 2003-11-21 NotInFoster
10:  1  2003-11-22 2005-06-01    InFoster
11:  1  2005-06-02 2015-03-02 NotInFoster
12:  1  2015-03-03 2019-02-08    InFoster
13:  1  2019-02-09 2020-01-02 NotInFoster
14:  2  1988-05-02 1993-04-20 NotInFoster
15:  2  1993-04-21 1993-05-12    InFoster
16:  2  1993-05-13 1993-05-12 NotInFoster
17:  2  1993-05-13 1996-01-30    InFoster
18:  2  1996-01-31 1998-02-18 NotInFoster
19:  2  1998-02-19 1998-02-28    InFoster
20:  2  1998-03-01 1999-03-01 NotInFoster
21:  3  2001-06-04 2005-01-30 NotInFoster
22:  3  2005-01-31 2006-08-19    InFoster
23:  3  2006-08-20 2011-05-06 NotInFoster
    id spell_start  spell_end  spell_type
library(data.table)
participants <- data.frame(id = 1:3, 
    doe = c("1990/01/04","1988/05/02","2001/06/04"), 
    dox = c("2020/01/02","1999/03/01","2011/05/06"))
placement_dates<-data.frame(
      id = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L),
      placement_start = c("1993/04/21","1994/12/04","1994/12/19",
             "2000/01/14","2003/11/22","2015/03/03","1993/04/21",
             "1993/05/13","1998/02/19","2005/01/31"),
      placement_end = c("1993/06/01","1994/12/06","1995/05/02",
             "2002/12/04","2005/06/01","2019/02/08","1993/05/12",
             "1996/01/30","1998/02/28","2006/08/19"))

cols <- c("doe","dox")
setDT(participants)[, (cols) := lapply(.SD, as.Date, format="%Y/%m/%d"), .SDcols=cols]
cols <- c("placement_start","placement_end")
setDT(placement_dates)[, (cols) := lapply(.SD, as.Date, format="%Y/%m/%d"), .SDcols=cols]