любой способ восстановить новый фрейм данных, суммируя различные столбцы условно в R? - PullRequest
1 голос
/ 24 марта 2020

Я пытаюсь восстановить новый фрейм данных из входных данных путем суммирования и обработки различных столбцов. Я использовал dplyr утилиты для выполнения sh, но я не получил ожидаемый результат. По сути, в моих входных данных я намереваюсь сначала group_by субъект, затем суммировать его по transfer_time, а затем выяснить, есть ли у субъекта строка ICU в столбце environment и строка Intensive в столбце level , Я нашел способ сделать это, сначала получив два субкадра данных, затем объединив их по общему столбцу subject, но объединенный фрейм данных не соответствует ожиданиям.

воспроизводимые данные

вот воспроизводимые данные на публике c gist , взятые из исходных входных данных

моя текущая попытка

library(dplyr)

dat = read.csv("mydf.csv", header = TRUE)
    df_1 <- dat %>% group_by(subject) %>% filter(grepl("Intensive", level)) %>% summarise(first_icu=min(transfer_time))
    df_1$first_icu <- ifelse(grepl("0", df_1$first_icu_transfer_time), 1, NA)
    df_2 = dat %>% group_by(subject) %>% summarise(flag = sum(unique(grepl('ICU',environment) & grepl("Intensive", level))))
    final_df <- merge(df_1, df_2, by.x="subject", by.y="subject") %>% write.csv(.,file = "newdf.csv")

, но вышеприведенная попытка на самом деле не верна.

ожидаемый результат

вот мое точное ожидаемое выходной фрейм данных, который я сделал вручную, следующим образом:

subject   first_icu_transfer  icu_flag
subject1  NA  0
subject2  NA  0
subject3  154 1
subject4  NA  0
subject5  571 1
subject6  NA  0
subject7  298 1

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

1 Ответ

3 голосов
/ 24 марта 2020

Один из способов исправить поведение - добавить complete в конце

library(dplyr)
library(tidyr)
final_df <- merge(df_1, df_2, by.x="subject", by.y="subject")
final_df %>%
       complete(subject = paste('Subject', 1:7), fill = list(flag = 0))
# A tibble: 7 x 3
#  subject   first_icu  flag
#  <chr>         <int> <dbl>
#1 Subject 1        NA     0
#2 Subject 2        NA     0
#3 Subject 3       154     1
#4 Subject 4        NA     0
#5 Subject 5       571     1
#6 Subject 6        NA     0
#7 Subject 7       298     1

или в merge использовать all = TRUE

merge(df_1, df_2, by.x="subject", by.y="subject", all = TRUE)
#   subject first_icu flag
#1 Subject 1        NA    0
#2 Subject 2        NA    0
#3 Subject 3       154    1
#4 Subject 4        NA    0
#5 Subject 5       571    1
#6 Subject 6        NA    0
#7 Subject 7       298    1

Или, если нам нужно сделать это несколько более компактным способом

library(stringr)
dat %>% 
   group_by(subject) %>%
   summarise(first_icu = min(transfer_time[str_detect(level, 'Intensive')], na.rm = TRUE), 
   flag = +(sum(str_detect(environment, 'ICU') & str_detect(level, 'Intensive')) > 0)) %>%
   mutate(first_icu = na_if(first_icu, Inf))

В base R, мы можем сделать

out <- do.call(rbind, lapply(split(dat, dat$subject), 
 function(x) data.frame(subject = x$subject[1], 
     first_icu = min(x$transfer_time[grepl(x = x$level, 
   'Intensive')], na.rm = TRUE), 
   flag = sum(grepl("ICU", x$environment) & grepl("Intensive", x$level)))))

 out$first_icu[is.infinite(out$first_icu)] <- NA
 out$flag <- +(out$flag > 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...