Skip to content

Commit

Permalink
updated more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
gowerc committed Sep 10, 2021
1 parent 2851594 commit 64c798a
Show file tree
Hide file tree
Showing 21 changed files with 505 additions and 94 deletions.
167 changes: 144 additions & 23 deletions R/analyse.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,113 @@



#' Title
#' Analyse Multiple Imputed Datasets
#'
#' @description
#' TODO
#' This function takes multiple imputed datasets (as generated by
#' the [impute()] function) and runs an analysis function on
#' each of them.
#'
#' @param imputations TODO
#' @param fun TODO
#' @param delta TODO
#' @param ... TODO
#' @details
#' This function works by performing the following steps
#'
#' 1. Extract a dataset from the `imputations` object
#' 2. Apply any delta adjustments as specified by the `delta` argument
#' 3. Run the analysis function `fun` on the dataset
#' 4. Repeat steps 1-3 across all of the datasets inside the `imputations`
#' object
#' 5. Collect and return all of the analysis results.
#'
#' The analysis function `fun` must take a data.frame as its first
#' argument. All other options to [analyse()] are passed onto `fun`
#' via `...`.
#' `fun` must return a named list with each element being itself a
#' list containing a single
#' numeric element called `est` (or additionally `se` and `df` if using
#' you had originally specified [method_bayes()] or [method_approxbayes()])
#' i.e.
#' ```
#' myfun <- function(dat, ...) {
#' mod_1 <- lm(data = dat, outcome ~ group)
#' mod_2 <- lm(data = dat, outcome ~ group + covar)
#' x <- list(
#' trt_1 = list(
#' est = coef(mod_1)[[group]],
#' se = sqrt(vcov(mod_1)[group, group]),
#' df = df.residual(mod_1)
#' ),
#' trt_2 = list(
#' est = coef(mod_2)[[group]],
#' se = sqrt(vcov(mod_2)[group, group]),
#' df = df.residual(mod_2)
#' )
#' )
#' return(x)
#' }
#' ```
#'
#' Please note that the `vars$subjid` column (as defined in the original call to
#' [draws()]) will be scrambled in the data.frames that are provided to `fun`.
#' This is to say they will not contain the original subject values and as such
#' any hard coding of subject ids is strictly to be avoided.
#'
#' By default `fun` is the [ancova()] function.
#' Please note that this function
#' requires that a vars object, as created by [set_vars()], is provided via
#' the `vars` arguement. i.e. `analyse(imputeObj, vars = set_vars(...))` Please
#' see the documentation for [ancova()] for full details.
#'
#' The `delta` argument can be used to specify offsets to be applied
#' to the outcome variable in the imputed datasets in order to
#' perform a "tipping point" analysis. The
#' delta dataset must contain columns `vars$subjid`, `vars$visit` (as specified
#' in the original call to [draws()]) and `delta`. Essentially this data.frame
#' is merged onto the imputed dataset by `vars$subjid` & `vars$visit` and then
#' the outcome variable is modified by:
#' ```
#' imputed_data[[vars$outcome]] <- imputed_data[[vars$outcome]] + imputed_dat[["delta"]]
#' ```
#' The helper functions [delta_template()] & [delta_lagscale()] can be used
#' to create delta datasets.
#'
#' @seealso [extract_imputed_dfs()] for manually extracting imputed
#' datasets.
#' @seealso [delta_template()] & [delta_lagscale()] for creating delta data.frames
#' @seealso [ancova()] for the default analysis function
#'
#' @param imputations An imputations object as created by [impute()]
#' @param fun An analysis function to be applied to each imputed datset. See details.
#' @param delta A data.frame containing the delta transformation to be applied to the imputed dataset prior to running `fun`. See details.
#' @param ... Additional arguments passed onto `fun`
#' @examples
#' \dontrun{
#' vars <- set_vars(
#' subjid = "subjid",
#' visit = "visit",
#' outcome = "outcome",
#' group = "group",
#' covariates = c("sex", "age", "sex*age")
#' )
#'
#' analyse(
#' imputations = imputeObj,
#' vars = vars
#' )
#'
#' deltadf <- data.frame(
#' subjid = c("Pt1", "Pt1", "Pt2"),
#' visit = c("Visit_1", "Visit_2", "Visit_2"),
#' delta = c( 5, 9, -10)
#' )
#'
#' analyse(
#' imputations = imputeObj,
#' delta = deltadf,
#' vars = vars
#' )
#' }
#' @export
analyse <- function(imputations, fun, delta = NULL, ...) {
analyse <- function(imputations, fun = ancova, delta = NULL, ...) {

analysis_call <- match.call()

Expand Down Expand Up @@ -70,16 +165,33 @@ analyse <- function(imputations, fun, delta = NULL, ...) {



#' Extract imputated datasets
#' Extract imputed datasets
#'
#' @description
#' TODO
#' Extracts the imputed datasets contained with an imputations object generated
#' by [impute()].
#'
#' @param imputations TODO
#' @param index TODO
#' @param delta TODO
#' @param idmap TODO
#' @param imputations An imputations object as created by [impute()]
#' @param index The indexes of the imputed data.frames to return. By default will
#' return all data.frames within the imputations object.
#' (i.e. use this argument if you just want the "1st" data.frame)
#' @param delta A data.frame containing the delta transformation to be
#' applied to the imputed dataset. See [analyse()] for details on the
#' format and specification of this data.frame
#' @param idmap Logical. The subject IDs in the imputed data.frame will be scrambled
#' setting this argument to True will add an attribute called "idmap" to the
#' imputed data.frame which will provide a map from the new subect IDs to the old
#' subject IDs
#'
#' @examples
#' \dontrun{
#' extract_imputed_dfs(imputeObj)
#' extract_imputed_dfs(imputeObj, c(1:3))
#' }
#' @returns
#' A list of data.frames equal in length to the `index` argument
#' @seealso [delta_template()] & [delta_lagscale()] for creating delta data.frames
#' @seealso [analyse()]
#' @export
extract_imputed_dfs <- function(
imputations,
Expand All @@ -95,15 +207,24 @@ extract_imputed_dfs <- function(
}


#' Extract imputated dataset
#' Extract imputed dataset
#'
#' @description
#' TODO
#' Takes an imputation object as generated by [as_imputation_list()] and uses
#' this to extract a completed dataset from a longdata object as created
#' by [longDataConstructor()]. Also applies a delta transformation
#' if a data.frame is provided to the `delta` argument. See [analyse()] for
#' details on the structure of this data.frame.
#'
#' @param imputation TODO
#' @param ld TODO
#' @param delta TODO
#' @param idmap TODO
#' Subject IDs in the returned dataframe are scrambled i.e. are not the original
#' values.
#'
#' @param imputation An imputation object as generated by [as_imputation_list()]
#' @param ld A Longdata object as generated by [longDataConstructor()]
#' @param delta Either Null or a data.frame. Is used to offset outcome values in the imputed dataset
#' @param idmap Logical. If true a attaches an attribute called "idmap" which
#' contains a mapping from the old subject ids to the new subject ids.
#' @returns A data.frame
extract_imputed_df <- function(imputation, ld, delta = NULL, idmap = FALSE) {

vars <- ld$vars
Expand Down Expand Up @@ -139,7 +260,7 @@ extract_imputed_df <- function(imputation, ld, delta = NULL, idmap = FALSE) {


#' TODO
#'
#'
#' @param results TODO
#' @param method TODO
#' @param delta TODO
Expand Down Expand Up @@ -212,9 +333,9 @@ print.analysis <- function(x, ...) {


#' Validate Analysis Objects
#'
#'
#' Validates the return object of the analyse() function
#'
#'
#' @param x A Analysis results object (of class "jackknife", "bootstrap", "rubin")
#' @param ... Not Used
#' @export
Expand Down Expand Up @@ -267,7 +388,7 @@ validate.rubin <- function(x, ...) {


#' TODO
#'
#'
#' @param results TODO
#' @param pars TODO
#' @export
Expand Down
28 changes: 23 additions & 5 deletions R/bootstrap.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@


#' Title
#' Create vector of Stratas
#'
#' @param ... TODO
#' Collapse multiple categorical variables into distinct unique categories.
#' i.e.
#' ```
#'
#' ```
#' would return
#' ```
#' c(1,2,3,3,4,1)
#' ```
#'
#' @param ... numeric/character/fator vectors of the same length
#' @examples
#' as_strata(c(1,1,2,2,2,1), c(5,6,5,5,6,5))
as_strata <- function(...){
x <- list(...)
assert_that(length(unique(vapply(x, length, numeric(1)))) == 1 )
df <- as.data.frame(x)
colnames(df) <- paste0("var", 1:length(x))
df_unique <- unique(df)
Expand All @@ -16,11 +28,17 @@ as_strata <- function(...){
}


#' Title
#' Sample Patient Ids
#'
#' Performs stratified random sampling with replacement of patient IDs
#' ensuring the return vector is the same length as the input vector
#'
#' @param ids TODO
#' @param strata TODO
#' @param ids vector to sample from
#' @param strata strata indicator, ids are sampled within each strata
#' ensuring the that the numbers of each strata are maintained
#'
#' @examples
#' sample_ids( c("a", "b", "c", "d"), strata = c(1,1,2,2))
sample_ids <- function(ids, strata = rep(1, length(ids))){
res <- tapply(
X = ids,
Expand Down
1 change: 0 additions & 1 deletion R/expand.R
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ locf <- function(x) {
#'
#' @examples
#' \dontrun{
#'
#' dat_expanded <- expand(
#' data = dat,
#' subject = c("pt1", "pt2", "pt3", "pt4"),
Expand Down
6 changes: 3 additions & 3 deletions R/impute.R
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
#' references = c("Trt" = "Placebo", "Placebo" = "Placebo")
#' )
#'
#' new_ice <- data.frame(
#' new_strategy <- data.frame(
#' subjid = c("Pt1", "Pt2"),
#' strategy = c("MAR", "JR")
#' )
Expand Down Expand Up @@ -136,7 +136,7 @@ impute_internal <- function(draws, references, update_strategy, strategies, cond
validate(references, data$data[[data$vars$group]])
validate_strategies(strategies, data$strategies)



if (!is.null(update_strategy)) {
data$update_strategies(update_strategy)
Expand Down Expand Up @@ -505,7 +505,7 @@ get_conditional_parameters <- function(pars, values) {
#'
#' @return
#' Will error if there is an issue otherwise will return `TRUE`
#' @export
#' @export
validate.references <- function(x, control, ...) {
references <- x
ref_names <- names(references)
Expand Down
2 changes: 1 addition & 1 deletion R/longData.R
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ longDataConstructor <- R6::R6Class(
self$ids,
function(x) self$indexes[[x]][[1]],
numeric(1),
use.names = FALSE
USE.NAMES = FALSE
)
strata_data <- self$data[strata_index, self$vars$strata]
self$strata <- as_strata(strata_data)
Expand Down
43 changes: 37 additions & 6 deletions R/lsmeans.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@


#' Title - TODO
#'
#'
#' @param data TODO
#' @param mterms TODO
#' @param fix TODO
#'
#'
lscombinations <- function(data, mterms, fix) {
x <- lapply(
mterms,
Expand Down Expand Up @@ -34,10 +34,40 @@ lscombinations <- function(data, mterms, fix) {
}


#' Title - TODO
#'
#' @param model TODO
#' @param ... TODO
#' Least Square Means
#'
#' Estimates the least square means from a linear model. This is
#' essentially where we generate a prediction from the model
#' by fitting it to some hypothetical observation that is constructed
#' by averaging the data. See details for more information.
#'
#' @details
#' Numeric variables are evaluated at the mean across the entire dataset
#' (after removing missing values)
#' Factor variables are evaluated at all levels (including combinations
#' with other factor variables) with the final return value being
#' average across all the predictions generated at each of these levels.
#'
#' Use the `...` argument to fix specific variables to specific values.
#'
#' See the references for identical implementations as done in SAS and via
#' the emmeans package. This function attempts to re-implement the
#' emmeans derivation for standard lm's but without having to include
#' all of their dependencies
#'
#' @param model A model created by lm
#' @param ... Fixes specific variables to specific values i.e.
#' `trt = 1` or `age = 50`. The name of the argument must be the name
#' of the variable within the dataset
#'
#' @references \url{https://cran.r-project.org/web/packages/emmeans/index.html}
#' @references \url{https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.3/statug/statug_glm_details41.htm}
#' @examples
#' mod <- lm( Sepal.Length ~ Species + Petal.Length, data = iris)
#' lsmeans(mod)
#' lsmeans(mod, Species = "virginica")
#' lsmeans(mod, Species = "versicolor")
#' lsmeans(mod, Species = "versicolor", Petal.Length = 1)
#' @importFrom stats model.matrix terms reformulate
lsmeans <- function(model, ...) {

Expand Down Expand Up @@ -71,3 +101,4 @@ lsmeans <- function(model, ...) {
df = df.residual(model)
)
}

Loading

0 comments on commit 64c798a

Please sign in to comment.