Суммирующие диапазоны дат - PullRequest
0 голосов
/ 01 октября 2018

У меня есть фрейм данных с PatientID и датами, отсортированными по порядку дат в пределах ID.У каждого пациента обычно есть несколько строк, хотя возможно иметь только одну.Например:

patid   date
1302    2009-01-27
1302    2009-02-05
1302    2009-08-28
1670    2009-03-12
2073    2009-04-03
2073    2010-11-01
2073    2010-12-19
2073    2011-03-06

Исходя из этого, я хочу создать файл данных или файл CSV с датами начала и окончания для каждого пациента, поэтому из вышеприведенного я получу

patid   start       end
1302    2009-01-27  2009-08-28
1670    2009-03-12  2009-03-12
2073    2009-04-03  2011-03-06

У меня более 30 миллионов строк в исходном файле, поэтому я бы предпочел не писать цикл for.

Интересно, есть ли эффективный способ сделать это, возможно, начать с использования * 1010?* получить количество строк для каждого пациента?

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

С tidyverse:

read.table(text="patid   date
           1302    2009-01-27
           1302    2009-02-05
           1302    2009-08-28
           1670    2009-03-12
           2073    2009-04-03
           2073    2010-11-01
           2073    2010-12-19
           2073    2011-03-06",header=T)%>%
   group_by(patid)%>%
   mutate(date=lubridate::ymd(date))%>%
   summarise(start=min(date),
             end=max(date))
# A tibble: 3 x 3
  patid start      end       
  <int> <date>     <date>    
1  1302 2009-01-27 2009-08-28
2  1670 2009-03-12 2009-03-12
3  2073 2009-04-03 2011-03-06
0 голосов
/ 02 октября 2018

Использование базовой функции R aggregate() с FUN = простая пользовательская функция для возврата вектора двух выходов min() и max() за один шаг:

Как вы и предлагали, вы можете использовать aggregate() - но, как показано ниже, вы можете сделать это за один шаг, чтобы рассчитать min() и max() для каждой patid группы

# Read in your sample data, being careful to prevent dates from becoming factors
pdates <- 
  read.table( text="patid   date
                    1302    2009-01-27
                    1302    2009-02-05
                    1302    2009-08-28
                    1670    2009-03-12
                    2073    2009-04-03
                    2073    2010-11-01
                    2073    2010-12-19
                    2073    2011-03-06",
                    header=TRUE, 
                    stringsAsFactors=FALSE) # keep date strings from becoming factors!

aggregate( x = pdates["date"],   # dataframe with column(s) to aggregate
           by = pdates["patid"], # passing dataframe with named column "patid" preserves the column name in the output
           FUN = function(vdate) { 
                   c(start=min(vdate), end=max(vdate))
                 }  
         )

  patid date.start   date.end
1  1302 2009-01-27 2009-08-28
2  1670 2009-03-12 2009-03-12
3  2073 2009-04-03 2011-03-06

РЕДАКТИРОВАТЬ: Или, еще проще, используяполезная база R range() функция:

aggregate( pdates["date"], by=pdates["patid"], range)

  patid     date.1     date.2
1  1302 2009-01-27 2009-08-28
2  1670 2009-03-12 2009-03-12
3  2073 2009-04-03 2011-03-06
0 голосов
/ 01 октября 2018

Использование sqldf:

входные данные:

df=read.table(text="patid   date
          1302    2009-01-27
          1302    2009-02-05
          1302    2009-08-28
          1670    2009-03-12
          2073    2009-04-03
          2073    2010-11-01
          2073    2010-12-19
          2073    2011-03-06",header=T)

Код

 library(sqldf)
 sqldf("select patid,min(date) as start, max(date) as end from df group by patid")

Вывод:

   patid      start        end
1  1302 2009-01-27 2009-08-28
2  1670 2009-03-12 2009-03-12
3  2073 2009-04-03 2011-03-06
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...