% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/get_episode.R
\name{get_episode}
\alias{get_episode}
\alias{is_new_episode}
\title{Determine Clinical or Epidemic Episodes}
\usage{
get_episode(x, episode_days = NULL, case_free_days = NULL, ...)

is_new_episode(x, episode_days = NULL, case_free_days = NULL, ...)
}
\arguments{
\item{x}{Vector of dates (class \code{Date} or \code{POSIXt}), will be sorted internally to determine episodes.}

\item{episode_days}{Episode length in days to specify the time period after which a new episode begins, can also be less than a day or \code{Inf}, see \emph{Details}.}

\item{case_free_days}{(inter-epidemic) interval length in days after which a new episode will start, can also be less than a day or \code{Inf}, see \emph{Details}.}

\item{...}{Ignored, only in place to allow future extensions.}
}
\value{
\itemize{
\item \code{\link[=get_episode]{get_episode()}}: an \link{integer} vector
\item \code{\link[=is_new_episode]{is_new_episode()}}: a \link{logical} vector
}
}
\description{
These functions determine which items in a vector can be considered (the start of) a new episode. This can be used to determine clinical episodes for any epidemiological analysis. The \code{\link[=get_episode]{get_episode()}} function returns the index number of the episode per group, while the \code{\link[=is_new_episode]{is_new_episode()}} function returns \code{TRUE} for every new \code{\link[=get_episode]{get_episode()}} index. Both absolute and relative episode determination are supported.
}
\details{
Episodes can be determined in two ways: absolute and relative.
\enumerate{
\item Absolute

This method uses \code{episode_days} to define an episode length in days, after which a new episode will start. A common use case in AMR data analysis is microbial epidemiology: episodes of \emph{S. aureus} bacteraemia in ICU patients for example. The episode length could then be 30 days, so that new \emph{S. aureus} isolates after an ICU episode of 30 days will be considered a different (or new) episode.

Thus, this method counts \strong{since the start of the previous episode}.
\item Relative

This method uses \code{case_free_days} to quantify the duration of case-free days (the inter-epidemic interval), after which a new episode will start. A common use case is infectious disease epidemiology: episodes of norovirus outbreaks in a hospital for example. The case-free period could then be 14 days, so that new norovirus cases after that time will be considered a different (or new) episode.

Thus, this methods counts \strong{since the last case in the previous episode}.
}

In a table:\tabular{ccc}{
   Date \tab Using \code{episode_days = 7} \tab Using \code{case_free_days = 7} \cr
   2023-01-01 \tab 1 \tab 1 \cr
   2023-01-02 \tab 1 \tab 1 \cr
   2023-01-05 \tab 1 \tab 1 \cr
   2023-01-08 \tab 2** \tab 1 \cr
   2023-02-21 \tab 3 \tab 2*** \cr
   2023-02-22 \tab 3 \tab 2 \cr
   2023-02-23 \tab 3 \tab 2 \cr
   2023-02-24 \tab 3 \tab 2 \cr
   2023-03-01 \tab 4 \tab 2 \cr
}


** This marks the start of a new episode, because 8 January 2023 is more than 7 days since the start of the previous episode (1 January 2023). \cr
*** This marks the start of a new episode, because 21 January 2023 is more than 7 days since the last case in the previous episode (8 January 2023).

Either \code{episode_days} or \code{case_free_days} must be provided in the function.
\subsection{Difference between \code{get_episode()} and \code{is_new_episode()}}{

The \code{\link[=get_episode]{get_episode()}} function returns the index number of the episode, so all cases/patients/isolates in the first episode will have the number 1, all cases/patients/isolates in the second episode will have the number 2, etc.

The \code{\link[=is_new_episode]{is_new_episode()}} function on the other hand, returns \code{TRUE} for every new \code{\link[=get_episode]{get_episode()}} index.

To specify, when setting \code{episode_days = 365} (using method 1 as explained above), this is how the two functions differ:\tabular{cccc}{
   patient \tab date \tab \code{get_episode()} \tab \code{is_new_episode()} \cr
   A \tab 2019-01-01 \tab 1 \tab TRUE \cr
   A \tab 2019-03-01 \tab 1 \tab FALSE \cr
   A \tab 2021-01-01 \tab 2 \tab TRUE \cr
   B \tab 2008-01-01 \tab 1 \tab TRUE \cr
   B \tab 2008-01-01 \tab 1 \tab FALSE \cr
   C \tab 2020-01-01 \tab 1 \tab TRUE \cr
}

}

\subsection{Other}{

The \code{\link[=first_isolate]{first_isolate()}} function is a wrapper around the \code{\link[=is_new_episode]{is_new_episode()}} function, but is more efficient for data sets containing microorganism codes or names and allows for different isolate selection methods.

The \code{dplyr} package is not required for these functions to work, but these episode functions do support \link[dplyr:group_by]{variable grouping} and work conveniently inside \code{dplyr} verbs such as \code{\link[dplyr:filter]{filter()}}, \code{\link[dplyr:mutate]{mutate()}} and \code{\link[dplyr:summarise]{summarise()}}.
}
}
\examples{
# difference between absolute and relative determination of episodes:
x <- data.frame(dates = as.Date(c(
  "2021-01-01",
  "2021-01-02",
  "2021-01-05",
  "2021-01-08",
  "2021-02-21",
  "2021-02-22",
  "2021-02-23",
  "2021-02-24",
  "2021-03-01",
  "2021-03-01"
)))
x$absolute <- get_episode(x$dates, episode_days = 7)
x$relative <- get_episode(x$dates, case_free_days = 7)
x


# `example_isolates` is a data set available in the AMR package.
# See ?example_isolates
df <- example_isolates[sample(seq_len(2000), size = 100), ]

get_episode(df$date, episode_days = 60) # indices
is_new_episode(df$date, episode_days = 60) # TRUE/FALSE

# filter on results from the third 60-day episode only, using base R
df[which(get_episode(df$date, 60) == 3), ]

# the functions also work for less than a day, e.g. to include one per hour:
get_episode(
  c(
    Sys.time(),
    Sys.time() + 60 * 60
  ),
  episode_days = 1 / 24
)

\donttest{
if (require("dplyr")) {
  # is_new_episode() can also be used in dplyr verbs to determine patient
  # episodes based on any (combination of) grouping variables:
  df \%>\%
    mutate(condition = sample(
      x = c("A", "B", "C"),
      size = 100,
      replace = TRUE
    )) \%>\%
    group_by(patient, condition) \%>\%
    mutate(new_episode = is_new_episode(date, 365)) \%>\%
    select(patient, date, condition, new_episode) \%>\%
    arrange(patient, condition, date)
}

if (require("dplyr")) {
  df \%>\%
    group_by(ward, patient) \%>\%
    transmute(date,
      patient,
      new_index = get_episode(date, 60),
      new_logical = is_new_episode(date, 60)
    ) \%>\%
    arrange(patient, ward, date)
}

if (require("dplyr")) {
  df \%>\%
    group_by(ward) \%>\%
    summarise(
      n_patients = n_distinct(patient),
      n_episodes_365 = sum(is_new_episode(date, episode_days = 365)),
      n_episodes_60 = sum(is_new_episode(date, episode_days = 60)),
      n_episodes_30 = sum(is_new_episode(date, episode_days = 30))
    )
}

# grouping on patients and microorganisms leads to the same
# results as first_isolate() when using 'episode-based':
if (require("dplyr")) {
  x <- df \%>\%
    filter_first_isolate(
      include_unknown = TRUE,
      method = "episode-based"
    )

  y <- df \%>\%
    group_by(patient, mo) \%>\%
    filter(is_new_episode(date, 365)) \%>\%
    ungroup()

  identical(x, y)
}

# but is_new_episode() has a lot more flexibility than first_isolate(),
# since you can now group on anything that seems relevant:
if (require("dplyr")) {
  df \%>\%
    group_by(patient, mo, ward) \%>\%
    mutate(flag_episode = is_new_episode(date, 365)) \%>\%
    select(group_vars(.), flag_episode)
}
}
}
\seealso{
\code{\link[=first_isolate]{first_isolate()}}
}
