将代表长时间间隔的行分成多行

时间:2019-01-16 14:50:41

标签: r dplyr

我有一个包含多行的数据框(小标题),每行包含一个IDNR,开始日期,结束日期和曝光状态。 IDNR是字符变量,开始和结束日期是日期变量,暴露状态是数字变量。这是前三行的样子:

# A tibble: 48,266 x 4

   IDNR                 start      end        exposure
   <chr>                <date>     <date>        <dbl>
 1 1                    2018-02-15 2018-07-01        0
 2 2                    2017-10-30 2018-07-01        0
 3 3                    2016-02-11 2016-12-03        1

# ... with 48,256 more rows

为了进行随时间变化的Cox回归,我想将行分成90天部分,同时保持开始和结束日期。这是我想要实现的示例。发生的情况是,新的结束日期是开始+ 90天,并创建了一个新行。该行的开始日期与上一行的结束日期相同。如果现在开始到结束之间的时间少于90天,则可以(对于IDNR 1和3),但是对于IDNR 2,时间仍然超过90天。因此,需要添加第三行。

# A tibble: 48,266 x 4
# Groups:   IDNR [33,240]
   IDNR                 start      end        exposure
   <chr>                <date>     <date>        <dbl>
 1 1                    2018-02-15 2018-05-16        0
 2 1                    2018-05-16 2018-07-01        0
 3 2                    2017-10-30 2018-01-28        0
 4 2                    2018-01-28 2018-04-28        0
 5 2                    2018-04-28 2018-07-01        0
 6 3                    2016-02-11 2016-08-09        1
 7 3                    2016-08-09 2016-12-03        1 

我对使用R进行编码相对较新,但是到目前为止,我发现dplyr非常有用。因此,如果有人知道使用dplyr的解决方案,我将非常感谢。

谢谢!

1 个答案:

答案 0 :(得分:1)

您在这里:

使用Sub Process() Dim lastrow As Long lastrow = ActiveSheet.Cells(ActiveSheet.Rows.Count, "B").End(xlUp).Row ActiveSheet.Cells(ActiveSheet.Rows.Count,Selection.Column).End(xlUp).Select ActiveCell.Offset(1, 1).Select ActiveCell.Formula "=SUM(B2:B" & lastrow & ")" End Sub 作为数据框:

df

要做:

df = data.frame(IDNR = 1:3, 
                start = c("2018-02-15","2017-10-30","2016-02-11"),
                end = c("2018-07-01","2018-07-01","2016-12-03"),
                exposure = c(0,0,1))

结果:

library(lubridate)    

newDF = apply(df, 1, function(x){
    newStart = seq(from = ymd(x["start"]), to = ymd(x["end"]), by = 90)
    newEnd = c(seq(from = ymd(x["start"]), to = ymd(x["end"]), by = 90)[-1], ymd(x["end"]))
    d = data.frame(IDNR = rep(x["IDNR"], length(newStart)), 
                   start = newStart, 
                   end = newEnd, 
                   exposure = rep(x["exposure"], length(newStart)))
})

newDF = do.call(rbind, newDF)

newDF = newDF[newDF$start != newDF$end,]

这是从> newDF IDNR start end exposure 1 1 2018-02-15 2018-05-16 0 2 1 2018-05-16 2018-07-01 0 3 2 2017-10-30 2018-01-28 0 4 2 2018-01-28 2018-04-28 0 5 2 2018-04-28 2018-07-01 0 6 3 2016-02-11 2016-05-11 1 7 3 2016-05-11 2016-08-09 1 8 3 2016-08-09 2016-11-07 1 9 3 2016-11-07 2016-12-03 1 start的90天之内创建一个序列,并与endIDNR一起创建一个较小的数据框。此应用将返回一个数据框列表,您可以使用exposure将其连接在一起。最后一行删除具有相同do.callstart日期的行