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

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

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

И янужно, чтобы они были преобразованы в:

Ward Adm_Date Dis_Date
A    1        4
B    4        4
A    4        7
C    7        10

Чтобы выразить это предложение, это запись о приеме пациента X, который:

  • идет в палату А со дня 1 по день 4
  • перейти в отделение B (может быть, отделение ICU) менее чем на один день в день 4 и вернуться в отделение A в этот день
  • оставаться в отделении A со дня 4 на день7
  • перейти в палату C из палаты A со дня 7 и оставаться в палате C до дня 10

Я думаю об использовании ddply путем фильтрации в палате, но это не такХорошо, так как B будет «опущен» и период времени для A не будет разбит на 2 части.

Есть предложения?Спасибо!

Ответы [ 2 ]

1 голос
/ 09 ноября 2010
dat <- data.frame(Date=1:10,Ward=c(rep("A",3),"A B",rep("A",2),"A C",rep("C",3)))
dat$Ward <- as.character(dat$Ward)

# Change data to a "long" format

Date2 <- rep(dat$Date,nchar(gsub(" ","",dat$Ward)))
Ward2 <- unlist(strsplit(dat$Ward," "))
dat2 <- data.frame(Date=Date2,Ward=Ward2)
dat2$Ward <- as.character(dat2$Ward) # pesky factors!

# Create output

Ward3 <- unlist(strsplit(gsub("(\\w)\\1+","\\1",paste(dat2$Ward,collapse="")),""))

#helper function to find lengths of repeated characters, probably a better way of doing this

repCharLength <- function(str)
{
    out <- numeric(0)
    tmp <- 1
    for (i in 2:length(str))
        {
        if (str[i]!=str[i-1])
            {out<-c(out,tmp)
            tmp<-1}
        else
        tmp <- tmp+1
        }
    return(c(out,tmp))
}

stays <- repCharLength(dat2$Ward)

Adm_Date <- c(1,dat2$Date[cumsum(stays)[1:(length(stays)-1)]])
Dis_Date <- dat2$Date[cumsum(stays)]
dat3 <- data.frame(Ward=Ward3,Adm_Date=Adm_Date,Dis_Date=Dis_Date)

> dat3
  Ward Adm_Date Dis_Date
1    A        1        4
2    B        4        4
3    A        4        7
4    C        7       10

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

Редактировать

В свете комментария Spacedman, есть библиотечная функция для вычисления Ward3 и stays:

Ward3 <- rle(dat2$Ward)$values
stays <- rle(dat2$Ward)$lengths
0 голосов
/ 09 ноября 2010

Это не сложный ответ, но вы можете преобразовать свои данные

X <- data.frame(
    Date=1:10,
    Ward=c("A","A","A","A B","A","A","A   C","C","C","C"),
    stringsAsFactors=FALSE
)

w <- strsplit(X$Ward," +")
n <- sapply(w, length)
X_mod <- data.frame(
    Date = rep(X$Date, n),
    Ward = unlist(w, FALSE, FALSE)
)

С помощью X_mod вы можете написать векторизованное (= быстрое) решение.Для начала with(X_mod, c(0,cumsum(Ward[-1]!=Ward[-length(Ward)]))) дает вам идентификатор посещения.

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