2010-11-12 2 views
2

Спасибо за предложение предложения по вопросу processing of hospital admission data using R, у меня есть вопрос по этому вопросу, на самом деле это должно быть задачей перед этим вопросом.обработка данных госпитализации с использованием R (часть II)

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

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 mac hine), когда набор данных имеет 8818 unique(Patients_ID) и 1861 unique(Date). Как я могу улучшить это? Благодаря!

ответ

3

Что-то, что работает это, предполагая, что ваши данные находятся в объекте 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 секунд (~ четыре раза).

Смежные вопросы