【问题标题】:R conditionally copy row datesR有条件地复制行日期
【发布时间】:2023-03-07 21:58:01
【问题描述】:

我正在尝试在 R 中创建一个数据框,但发现它很难。我将不胜感激任何帮助。我有以下类型的数据框。

       case_id    event  eventDate  
1           1       A    2000-07-25  
2           1       A    2014-02-25
3           1       B    2014-07-07
4           2       A    2000-03-12
5           2       A    2000-06-06
6           2       A    2000-09-05
7           2       B    2015-12-16
8           2       A    2016-07-28
9           2       A    2017-03-03
10          3       A    2002-05-13
11          3       A    2002-06-12
12          3       B    2004-06-27
13          3       A    2004-07-11
14          4       B    2011-08-31
15          4       A    2012-04-21
16          4       B    2013-01-10

我想得到如下所示的输出: 首先,countof_eventA_before_B 变量是按组(case_id)在事件 B 之前事件 A 的计数。其次,事件 B 的完成日期是下一个事件 A 的日期,如果没有事件 A,则为今天的日期,也是按组。例如,如果事件 B 之后没有 A 事件,则第 3 行是今天的日期,第 7 行是组 case_id 中 B 之后的下一个 A 事件日期的副本

        case_id    event  eventDate  countof_eventA_before_B   finishDate
1           1       A    2000-07-25   NA                       NA 
2           1       A    2014-02-25   NA                       NA
3           1       B    2014-07-07   2                        2017-05-24  
4           2       A    2000-03-12   NA                       NA 
5           2       A    2000-06-06   NA                       NA
6           2       A    2000-09-05   NA                       NA
7           2       B    2015-12-16   3                        2016-07-28  
8           2       A    2016-07-28   NA                       NA
9           2       A    2017-03-03   NA                       NA
10          3       A    2002-05-13   NA                       NA
11          3       A    2002-06-12   NA                       NA
12          3       B    2004-06-27   2                        2004-06-27 
13          3       A    2004-07-11   NA                       NA
14          4       B    2011-08-31   0                        2012-04-21 
15          4       A    2012-04-21   NA                       NA
16          4       B    2013-01-10   1                        2017-05-24 

有人可以帮忙吗?提前谢谢你。

【问题讨论】:

  • 请重新格式化表格以使其可读
  • Marco,感谢您的编辑。

标签: r data.table dplyr


【解决方案1】:

这是一个有点笨拙的实现,但它有效:

#Read the data:
data<-fread("case_id    event  eventDate  countof_eventA_before_B   finishDate
1           1       A    2000-07-25   NA                       NA 
2           1       A    2014-02-25   NA                       NA
3           1       B    2014-07-07   2                        2017-05-24  
4           2       A    2000-03-12   NA                       NA 
5           2       A    2000-06-06   NA                       NA
6           2       A    2000-09-05   NA                       NA
7           2       B    2015-12-16   3                        2016-07-28  
8           2       A    2016-07-28   NA                       NA
9           2       A    2017-03-03   NA                       NA
10          3       A    2002-05-13   NA                       NA
11          3       A    2002-06-12   NA                       NA
12          3       B    2004-06-27   2                        2004-06-27 
13          3       A    2004-07-11   NA                       NA
14          4       B    2011-08-31   0                        2012-04-21 
15          4       A    2012-04-21   NA                       NA
16          4       B    2013-01-10   1                        2017-05-24 ")
data[,V1:=NULL]
setnames(data,c("case_id","event","eventDate","countof_eventA_before_B","finishDate"))

#Order data by case_id and eventDate:
data[,eventDatenum:=as.numeric(gsub("-","",eventDate))]
data<-data[order(case_id,eventDate)]

#Obtain all events by case_id:
data[,all_cases:=list(list(event)),by="case_id"]
data[,all_dates:=list(list(eventDate)),by="case_id"]
#Obtain order number of an event within case_id
data[,seq_nr:=seq_len(.N),by=c("case_id")]

#Define function calculating number of events:
function_seq<-function(x,y){
  as.numeric(sum(x[[1]][1:(y-1)]=="A"))
}

#Obtain function calculating needed date:
function_date<-function(x,y,z){
  x_aux<-x[[1]][(z+1):length(x[[1]])]
  y_aux<-y[[1]][(z+1):length(x[[1]])]
  if (sum(x_aux=="A",na.rm=TRUE)>0){
    as.character(y_aux[x_aux=="A"][1])
  } else{
    as.character(Sys.Date())
  }
}
data[,neeed_nr_events:=ifelse(event=="A",as.numeric(NA),function_seq(all_cases,seq_nr)),by=1:nrow(data)]
data[,neeed_dates:=ifelse(event=="A",as.character(NA),function_date(all_cases,all_dates,seq_nr)),by=1:nrow(data)]

data

    case_id event  eventDate countof_eventA_before_B finishDate eventDatenum   all_cases                                                         all_dates seq_nr neeed_nr_events neeed_dates
 1:       1     A 2000-07-25                      NA         NA     20000725       A,A,B                                  2000-07-25,2014-02-25,2014-07-07      1              NA          NA
 2:       1     A 2014-02-25                      NA         NA     20140225       A,A,B                                  2000-07-25,2014-02-25,2014-07-07      2              NA          NA
 3:       1     B 2014-07-07                       2 2017-05-24     20140707       A,A,B                                  2000-07-25,2014-02-25,2014-07-07      3               2  2017-05-24
 4:       2     A 2000-03-12                      NA         NA     20000312 A,A,A,B,A,A 2000-03-12,2000-06-06,2000-09-05,2015-12-16,2016-07-28,2017-03-03      1              NA          NA
 5:       2     A 2000-06-06                      NA         NA     20000606 A,A,A,B,A,A 2000-03-12,2000-06-06,2000-09-05,2015-12-16,2016-07-28,2017-03-03      2              NA          NA
 6:       2     A 2000-09-05                      NA         NA     20000905 A,A,A,B,A,A 2000-03-12,2000-06-06,2000-09-05,2015-12-16,2016-07-28,2017-03-03      3              NA          NA
 7:       2     B 2015-12-16                       3 2016-07-28     20151216 A,A,A,B,A,A 2000-03-12,2000-06-06,2000-09-05,2015-12-16,2016-07-28,2017-03-03      4               3  2016-07-28
 8:       2     A 2016-07-28                      NA         NA     20160728 A,A,A,B,A,A 2000-03-12,2000-06-06,2000-09-05,2015-12-16,2016-07-28,2017-03-03      5              NA          NA
 9:       2     A 2017-03-03                      NA         NA     20170303 A,A,A,B,A,A 2000-03-12,2000-06-06,2000-09-05,2015-12-16,2016-07-28,2017-03-03      6              NA          NA
10:       3     A 2002-05-13                      NA         NA     20020513     A,A,B,A                       2002-05-13,2002-06-12,2004-06-27,2004-07-11      1              NA          NA
11:       3     A 2002-06-12                      NA         NA     20020612     A,A,B,A                       2002-05-13,2002-06-12,2004-06-27,2004-07-11      2              NA          NA
12:       3     B 2004-06-27                       2 2004-06-27     20040627     A,A,B,A                       2002-05-13,2002-06-12,2004-06-27,2004-07-11      3               2  2004-07-11
13:       3     A 2004-07-11                      NA         NA     20040711     A,A,B,A                       2002-05-13,2002-06-12,2004-06-27,2004-07-11      4              NA          NA
14:       4     B 2011-08-31                       0 2012-04-21     20110831       B,A,B                                  2011-08-31,2012-04-21,2013-01-10      1               0  2012-04-21
15:       4     A 2012-04-21                      NA         NA     20120421       B,A,B                                  2011-08-31,2012-04-21,2013-01-10      2              NA          NA
16:       4     B 2013-01-10                       1 2017-05-24     20130110       B,A,B                                  2011-08-31,2012-04-21,2013-01-10      3               1  2017-05-24

这是一个单行解决方案:

data[,c("all_cases","all_dates","seq_nr"):=list(list(event),list(eventDate),seq_len(.N)),by=c("case_id")][,c("needed_nr_events","neeed_dates"):=list(ifelse(event=="A",as.numeric(NA),function_seq(all_cases,seq_nr)),
                                                                                                                                                     ifelse(event=="A",as.character(NA),function_date(all_cases,all_dates,seq_nr))),
                                                                                                          by=1:nrow(data)]

【讨论】:

  • 您好 Vitalijs,感谢您的回复。我已经成功地在一个更大的数据集中复制了您的解决方案,并进行了一些更改,并且效果很好。感谢您的宝贵时间。
  • @rlearner 我很高兴它有帮助,那么你能接受我的回答吗?meta.stackexchange.com/questions/5234/…
猜你喜欢
  • 2022-01-02
  • 2014-03-01
  • 1970-01-01
  • 2012-06-05
  • 2021-06-22
  • 2023-02-07
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
相关资源
最近更新 更多