R: итерации по серии дат для создания нескольких интервалов - PullRequest
0 голосов
/ 23 января 2020

Добрый вечер. Я ищу более простое решение неясной задачи, которую я имею с набором данных. Я уже решил это с помощью dplyr, но мне было интересно, есть ли у кого-то в сообществе более элегантное решение, возможно, с использованием purrr для моего собственного назидания.

У меня есть набор игрушечных данных с 3 идентификаторами исследований и 3 датами приема лекарств. Одна доза является NA. Я хотел бы сгенерировать 2 новые переменные: одну с именем «int_1», чтобы представить интервал времени между первыми двумя дозами, а затем «int_2», чтобы представить интервал между второй и третьей дозой.

library(dplyr)
library(lubridate)
study_id <- c(1001, 1002, 1003)
dose_1 <- c('1/1/10', '2/3/12', '1/1/13')
dose_2 <- c('1/10/10', '2/4/12', '1/2/13')
dose_3 <- c(NA, '3/1/12', '2/2/13')
df <- tibble(study_id, dose_1, dose_2, dose_3)
df <- df %>% 
  mutate_at(vars(contains('dose')),
            funs(mdy))

# A tibble: 3 x 4
  study_id dose_1     dose_2     dose_3    
     <dbl> <date>     <date>     <date>    
1     1001 2010-01-01 2010-01-10 NA        
2     1002 2012-02-03 2012-02-04 2012-03-01
3     1003 2013-01-01 2013-01-02 2013-02-02

Каким было бы ваше самое простое решение для получения следующего (только первый показанный интервал). Здесь я использовал метод dplyr / lubridate, с которым я знаком. На самом деле у меня есть 42 различных дозы, поэтому я ищу что-то более простое, чем копирование и вставка следующего кода 41 раз для создания различных интервалов. Мне нужно что-то, что может также справиться с отсутствующими дозами.

df <- df %>% 
  mutate(int_1 = interval(dose_1, dose_2),
         int_1 = int_1/months(1))

# A tibble: 3 x 5
  study_id dose_1     dose_2     dose_3      int_1
     <dbl> <date>     <date>     <date>      <dbl>
1     1001 2010-01-01 2010-01-10 NA         0.290 
2     1002 2012-02-03 2012-02-04 2012-03-01 0.0345
3     1003 2013-01-01 2013-01-02 2013-02-02 0.0323

Любые альтернативы этому подходу грубой силы очень ценятся. Что-то в мурлыканье?

1 Ответ

0 голосов
/ 23 января 2020

Обычно лучше иметь данные в длинном формате, а затем выполнить расчет

library(dplyr)
library(tidyr)
library(lubridate)

df %>%
  pivot_longer(cols = -study_id, names_to = 'dose') %>%
  group_by(study_id) %>%
  mutate(temp = interval(value, lead(value))/months(1)) %>%
  mutate(int = paste0('int', row_number())) %>%
  pivot_wider(names_from = c(dose, int), values_from = c(value, temp)) %>%
  select(-ncol(.))

#  study_id value_dose_1_int1 value_dose_2_int2 value_dose_3_int3 temp_dose_1_int1 temp_dose_2_int2
#     <dbl> <date>            <date>            <date>                       <dbl>            <dbl>
#1     1001 2010-01-01        2010-01-10        NA                          0.290            NA    
#2     1002 2012-02-03        2012-02-04        2012-03-01                  0.0345            0.897
#3     1003 2013-01-01        2013-01-02        2013-02-02                  0.0323            1    
...