% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/module_merge.R
\name{merge_srv}
\alias{merge_srv}
\title{Merge Server Function for Dataset Integration}
\usage{
merge_srv(
  id,
  data,
  selectors,
  output_name = "anl",
  join_fun = "dplyr::inner_join"
)
}
\arguments{
\item{id}{(\code{character(1)}) Module ID for the Shiny module namespace}

\item{data}{(\code{reactive}) A reactive expression returning a \link[teal.data:teal_data]{teal.data::teal_data} object containing
the source datasets to be merged. This object must have join keys defined via
\code{\link[teal.data:join_keys]{teal.data::join_keys()}} to enable proper dataset relationships.}

\item{selectors}{(\verb{named list}) A named list of selector objects. Each element can be:
\itemize{
\item A \code{picks} object defining dataset and variable selections
\item A \code{reactive} expression returning a \code{picks} object
The names of this list are used as identifiers for tracking which variables come from which selector.
}}

\item{output_name}{(\code{character(1)}) Name of the merged dataset that will be created in the
returned \code{teal_data} object. Default is \code{"anl"}. This name will be used in the generated R code.}

\item{join_fun}{(\code{character(1)}) The joining function to use for merging datasets. Must be a
qualified function name (e.g., \code{"dplyr::left_join"}, \code{"dplyr::inner_join"}, \code{"dplyr::full_join"}).
Default is \code{"dplyr::inner_join"}. The function must accept \code{by} and \code{suffix} parameters.}
}
\value{
A \code{list} with two reactive elements:
\itemize{
\item \code{data}A \code{reactive} returning a \link[teal.data:teal_data]{teal.data::teal_data} object containing the merged dataset.
The merged dataset is named according to \code{output_name} parameter. The \code{teal_data} object includes:
\itemize{
\item The merged dataset with all selected variables
\item Complete R code to reproduce the merge operation
\item Updated join keys reflecting the merged dataset structure
}
\item \code{variables} A \code{reactive} returning a named list mapping selector names to their selected
variables in the merged dataset. The structure is:
\code{list(selector_name_1 = c("var1", "var2"), selector_name_2 = c("var3", "var4"), ...)}.
Variable names reflect any renaming that occurred during the merge to avoid conflicts.
}
}
\description{
\code{merge_srv} is a powerful Shiny server function that orchestrates the merging of multiple datasets
based on user selections from \code{picks} objects. It creates a reactive merged dataset (\code{teal_data} object)
and tracks which variables from each selector are included in the final merged output.

This function serves as the bridge between user interface selections (managed by selectors) and
the actual data merging logic. It automatically handles:
\itemize{
\item Dataset joining based on join keys
\item Variable selection and renaming to avoid conflicts
\item Reactive updates when user selections change
\item Generation of reproducible R code for the merge operation
}
}
\section{How It Works}{


The \code{merge_srv} function performs the following steps:
\enumerate{
\item \strong{Receives Input Data}: Takes a reactive \code{teal_data} object containing source datasets with
defined join keys
\item \strong{Processes Selectors}: Evaluates each selector (whether static \code{picks} or reactive) to
determine which datasets and variables are selected
\item \strong{Determines Merge Order}: Uses topological sort based on the \code{join_keys} to determine
the optimal order for merging datasets.
\item \strong{Handles Variable Conflicts}: Automatically renames variables when:
\itemize{
\item Multiple selectors choose variables with the same name from different datasets
\item Foreign key variables would conflict with existing variables
\item Renaming follows the pattern \verb{\{column-name\}_\{dataset-name\}}
}
\item \strong{Performs Merge}: Generates and executes merge code that:
\itemize{
\item Selects only required variables from each dataset
\item Applies any filters defined in selectors
\item Joins datasets using specified join function and join keys
\item Maintains reproducibility through generated R code
}
\item \strong{Updates Join Keys}: Creates new join key relationships for the merged dataset (\code{"anl"})
relative to remaining datasets in the \code{teal_data} object
\item \strong{Tracks Variables}: Keeps track of the variable names in the merged dataset
}
}

\section{Usage Pattern}{


\if{html}{\out{<div class="sourceCode r">}}\preformatted{# In your Shiny server function
merged <- merge_srv(
  id = "merge",
  data = shiny::reactive(my_teal_data),
  selectors = list(
    selector1 = picks(...),
    selector2 = shiny::reactive(picks(...))
  ),
  output_name = "anl",
  join_fun = "dplyr::left_join"
)

# Access merged data
merged_data <- merged$data()  # teal_data object with merged dataset
anl <- merged_data[["anl"]]   # The actual merged data.frame/tibble

# Get variable mapping
vars <- merged$variables()
# Returns: list(selector1 = c("VAR1", "VAR2"), selector2 = c("VAR3", "VAR4_ADSL"))

# Get reproducible code
code <- teal.code::get_code(merged_data)
}\if{html}{\out{</div>}}
}

\section{Merge Logic Details}{


\strong{Dataset Order}: Datasets are merged in topological order based on join keys. The first dataset
acts as the "left" side of the join, and subsequent datasets are joined one by one.

\strong{Join Keys}: The function uses join keys from the source \code{teal_data} object to determine:
\itemize{
\item Which datasets can be joined together
\item Which columns to use for joining (the \code{by} parameter)
\item Whether datasets need intermediate joins (not yet implemented)
}

\strong{Variable Selection}: For each dataset being merged:
\itemize{
\item Selects user-chosen variables from selectors
\item Includes foreign key variables needed for joining (even if not explicitly selected)
\item Removes duplicate foreign keys after join (they're already in the left dataset)
}

\strong{Conflict Resolution}: When variable names conflict:
\itemize{
\item Variables from later datasets get suffixed with \verb{_dataname}
\item Foreign keys that match are merged (not duplicated)
\item The mapping returned in \code{merge_vars} reflects the final names
}
}

\section{Integration with Selectors}{


\code{merge_srv} is designed to work with \code{\link[=picks_srv]{picks_srv()}} which creates selector objects:

\if{html}{\out{<div class="sourceCode r">}}\preformatted{# Create selectors in server
selectors <- picks_srv(
  picks =  list(
    adsl = picks(...),
    adae = picks(...)
  ),
  data = data
)

# Pass to merge_srv
merged <- merge_srv(
  id = "merge",
  data = data,
  selectors = selectors
)
}\if{html}{\out{</div>}}
}

\examples{
# Complete example with CDISC data
library(teal.picks)
library(teal.data)
library(shiny)

# Prepare data with join keys
data <- teal_data()
data <- within(data, {
  ADSL <- teal.data::rADSL
  ADAE <- teal.data::rADAE
})
join_keys(data) <- default_cdisc_join_keys[c("ADSL", "ADAE")]

# Create Shiny app
ui <- fluidPage(
  picks_ui("adsl", picks(datasets("ADSL"), variables())),
  picks_ui("adae", picks(datasets("ADAE"), variables())),
  verbatimTextOutput("code"),
  verbatimTextOutput("vars")
)

server <- function(input, output, session) {
  # Create selectors
  selectors <- list(
    adsl = picks_srv("adsl",
      data = shiny::reactive(data),
      picks = picks(datasets("ADSL"), variables())
    ),
    adae = picks_srv("adae",
      data = shiny::reactive(data),
      picks = picks(datasets("ADAE"), variables())
    )
  )

  # Merge datasets
  merged <- merge_srv(
    id = "merge",
    data = shiny::reactive(data),
    selectors = selectors,
    output_name = "anl",
    join_fun = "dplyr::left_join"
  )

  # Display results
  output$code <- renderPrint({
    cat(teal.code::get_code(merged$data()))
  })

  output$vars <- renderPrint({
    merged$variables()
  })
}
if (interactive()) {
  shinyApp(ui, server)
}

}
\seealso{
\itemize{
\item \code{\link[=picks_srv]{picks_srv()}} for creating selectors
\item \code{\link[teal.data:join_keys]{teal.data::join_keys()}} for defining dataset relationships
}
}
