обработка данных о госпитализации с использованием R (часть II) - PullRequest
2 голосов
/ 12 ноября 2010

Спасибо всем за предложение по вопросу обработка данных о госпитализации с использованием R , у меня есть дополнительный вопрос по этому вопросу, на самом деле, перед этим вопросом должна стоять задача.

Теперь у меня есть такой набор данных:

Patient_ID Date Ward
P001       1    A
P001       2    A
P001       3    A
P001       4    A
P001       4    B
P001       5    B
P001       6    B
P001       7    B
P001       7    C
P001       8    B
P001       9    B
P001       10   B

Мне нужно преобразовать его в:

Patient_ID Date Ward
P001       1    A
P001       2    A
P001       3    A
P001       4    A;B
P001       5    B
P001       6    B
P001       7    B;C
P001       8    B
P001       9    B
P001       10   B

В настоящее время я преобразовал его, используя ddply, код прикреплен ниже:

data <- ddply(data,
              c("Patient_ID", "Date"),
              function(df)
                {data.frame(Ward=paste(unique(df[,"Ward"]),collapse=";"))
                },
              .progress="text"
              )

Это может решить мою проблему, но это ОЧЕНЬ медленно (более 20 минут на машине P4 3.2), когда набор данных имеет 8818 unique(Patients_ID) и 1861 unique(Date).Как я могу улучшить это?Спасибо!

1 Ответ

3 голосов
/ 12 ноября 2010

Что-то работает, если предположить, что ваши данные находятся в объекте pdat

res <- with(pdat,
            aggregate(Ward, by = list(Date = Date, Patient_ID = Patient_ID),
                      FUN = paste, collapse = ";"))
names(res)[3] <- "Ward"
res <- res[, c(2,1,3)]

и дает:

> res
   Patient_ID Date Ward
1        P001    1    A
2        P001    2    A
3        P001    3    A
4        P001    4  A;B
5        P001    5    B
6        P001    6    B
7        P001    7  B;C
8        P001    8    B
9        P001    9    B
10       P001   10    B

Он должен распространяться на большее количество пациентов и т. Д. И немного быстрее, чем ваша ddply() версия:

> system.time(replicate(1000,{
+ res <- with(pdat,
+             aggregate(Ward, by = list(Date = Date, Patient_ID = Patient_ID),
+                       FUN = paste, collapse = ";"))
+ names(res)[3] <- "Ward"
+ res <- res[, c(2,1,3)]
+ }))
   user  system elapsed 
  2.113   0.002   2.137

против

> system.time(replicate(1000,{
+ ddply(pdat,
+       c("Patient_ID", "Date"),
+       function(df)
+       data.frame(Ward=paste(unique(df[,"Ward"]),collapse=";"))
+       )
+ }))
   user  system elapsed 
 12.862   0.006  12.966

Однако это не означает, что ddply() нельзя ускорить - я не знаком с этим пакетом.

Независимо от того, масштабируются ли две версии одинаковым образом - то есть, просто потому, что версия aggregate() быстрее в этих повторных тестах на простых данных, не означает, что вы получите то же преимущество при применении к гораздо более крупной задаче Еще предстоит выяснить, но я оставлю вас для тестирования двух версий на небольших подмножествах ваших данных с несколькими пациентами, чтобы увидеть, насколько хорошо они масштабируются.


Edit: Быстрый тест - повторение данных о пациентах, которые вы нам дали, для генерации четырех новых пациентов (всего 5) с одинаковыми данными позволяет предположить, что совокупный показатель немного лучше. Время выполнения для версии aggregate() увеличилось до 4,6 секунды для 1000 повторений (~ удвоение), тогда как время для версии ddply() увеличилось до 52 секунд (~ в четыре раза).

...