Как объединить последовательные строки в одну строку на основе условия - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть кадр данных, содержащий эпизоды госпитализации с идентификаторами пациентов и датами.

Проблема

Я хотел бы объединить любую строку, где HospNum_Id - этокак и в предыдущей строке И разница в дате между двумя строками составляет> 3 дня.

Входные данные

Здесь показан синтетический набор данных:

structure(list(HospNum_Id = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L), .Label = c("A791697", "V682805", "X608693"
), class = "factor"), VisitDate = structure(c(17181, 17183, 17192, 
17168, 17169, 17186, 17189, 17212, 17215, 17167, 17173, 17190
), class = "Date"), diffDate = structure(c(-2, -9, NA, -1, -17, 
-3, -23, -3, NA, -6, -17, NA), class = "difftime", units = "days")), .Names = c("HospNum_Id", 
"VisitDate", "diffDate"), row.names = c(NA, -12L), class = "data.frame")

Мои попытки

Я предпринял следующие шаги:

1.Заказать столбцы

Mydf<-Mydf[order(Mydf$HospNum_Id,Mydf$VisitDate),]

2.Получите добавленный столбец различий дат

library(rlang)
library(dplyr)

SurveilTimeByRow <-
  function(Mydf, HospNum_Id, VisitDate) {
    HospNum_Ida <- sym(HospNum_Id)
    VisitDatea <- sym(VisitDate)
    ret<-dataframe %>% arrange(!!HospNum_Ida,!!VisitDatea) %>%
      group_by(!!HospNum_Ida) %>%
      mutate(diffDate = difftime(as.Date(!!VisitDatea), lead(as.Date(
        !!VisitDatea
      ), 1), units = "days"))
    dataframe<-data.frame(ret)
    return(dataframe)
  }

Mydf<-SurveilTimeByRow(try,"HospNum_Id","VisitDate")

3.Добавьте строку к предыдущей строке, если dateDiff для строки>> - 3 или <= 3 </h3> . Это часть, на которой я застрял. Требуемый вывод HospNum_Id VisitDate diffDate HospNum_Id.1 VisitDate.1 diffDate.1 A791697 2017-01-15 -2 days A791697 2017-01-17 -9 days V682805 2017-01-02 -1 days V682805 2017-01-03 -17 days V682805 2017-01-20 -3 days V682805 2017-01-23 -23 days V682805 2017-02-15 -3 days V682805 2017-02-18 NA days Я избавлюсь от последнего столбца difftime.1, который в итоге будет избыточным

1 Ответ

0 голосов
/ 19 сентября 2018

Вот одно из возможных решений с использованием данных, которые вы разместили как df:

library(tidyverse)

# create an id to flag consecutive rows within each HospNum
df %>%
  group_by(HospNum_Id) %>%
  mutate(id = ceiling(row_number() / 2)) %>%
  ungroup() -> df2

# split to even and odd rows within each HospNum
df_odd = df2 %>% group_by(HospNum_Id) %>% filter(row_number() %in% seq(1, nrow(df2), 2)) %>% ungroup()
df_even = df2 %>% group_by(HospNum_Id) %>% filter(row_number() %in% seq(2, nrow(df2), 2)) %>% ungroup()  

# join on both ids and remove rows
inner_join(df_odd, df_even, by=c("id","HospNum_Id")) %>%
  filter(between(diffDate.x, -3, 3) & !is.na(diffDate.y)) %>%
  select(-id)

# # A tibble: 3 x 5
#   HospNum_Id VisitDate.x diffDate.x VisitDate.y diffDate.y
#   <fct>      <date>      <time>     <date>      <time>    
# 1 A791697    2017-01-15  -2 days    2017-01-17  " -9 days"
# 2 V682805    2017-01-02  -1 days    2017-01-03  -17 days  
# 3 V682805    2017-01-20  -3 days    2017-01-23  -23 days 

Вы объединяете вышеуказанную логику в одну цепочку, как это:

df %>%
  group_by(HospNum_Id) %>%
  mutate(id = ceiling(row_number() / 2),
         even_row = row_number() %in% seq(2, nrow(df), 2)) %>%
  ungroup() %>%
  nest(-even_row) %>%
  pull(data) %>%
  reduce(function(x,y) inner_join(x,y,by=c("id","HospNum_Id"))) %>%
  filter(between(diffDate.x, -3, 3) & !is.na(diffDate.y)) %>%
  select(-id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...