Разбейте строки, представляющие длинные интервалы времени, на несколько строк - PullRequest
0 голосов
/ 16 января 2019

У меня есть фрейм данных (tibble) с несколькими строками, каждая строка содержит IDNR, дату начала, дату окончания и статус экспозиции. IDNR - это символьная переменная, дата начала и окончания - это переменные даты, а статус экспозиции - числовая переменная. Вот как выглядят 3 верхние строки:

# 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

Чтобы выполнить регрессию Кокса, меняющуюся во времени, я хочу разделить строки на 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 голосов
/ 16 января 2019

Вот, пожалуйста:

Использование 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))

Do:

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 до end на 90 дней и создает с ними меньший фрейм данных вместе с IDNR и exposure. Это действие вернет список фреймов данных, которые вы можете объединить, используя do.call. Последняя строка удаляет строки с одинаковыми start и end date

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...