R/estimate_pdiff_one.R

Defines functions estimate_pdiff_one.jamovi estimate_pdiff_one

Documented in estimate_pdiff_one

#' Estimate magnitudes of difference from a single measure compared to a know reference.
#'
#' @description
#' Returns effect sizes appropriate for designs with one quantitative variable
#' compared against a known reference.
#'
#' @param data For raw data - a dataframe or tibble
#' @param outcome_variable For raw data - The column name of the outcome
#'   variable, which must be a factor, or a vector that is a factor
#' @param comparison_cases For summary data, a numeric integer > 0
#' @param comparison_n For summary data, a numeric integer >= count
#' @param reference_p Reference proportion, numeric >=0 and <=1
#' @param case_label An optional numeric or character label for the
#'   count level.
#' @param outcome_variable_name Optional friendly name for the outcome variable.
#'   Defaults to 'My outcome variable' or the outcome variable column name if a
#'   data frame is passed.
#' @param conf_level The confidence level for the confidence interval.  Given in
#'   decimal form.  Defaults to 0.95.
#' @param count_NA Logical to count NAs (TRUE) in total N or not (FALSE)
#'
#'
#' @return Returns object of class esci_estimate
#'
#'
#' @examples
#' # From Raw Data ------------------------------------
#' # Just pass in the data source, grouping column, and outcome column.
#' # You can pass these in by position, skipping the labels:
#'
#' # Note... not sure if PlantGrowth dataset meets assumptions for this analysis
#' estimate_pdiff_one(
#'  datasets::PlantGrowth,
#'  group,
#'  reference_p = 0.33
#' )
#'
#' @export
estimate_pdiff_one <- function(
  data = NULL,
  outcome_variable = NULL,
  comparison_cases = NULL,
  comparison_n = NULL,
  reference_p = 0,
  case_label = 1,
  outcome_variable_name = "My outcome variable",
  conf_level = 0.95,
  count_NA = FALSE
) {


  # Check inputs -----------------------------------------------
  # * reference_p should be a numeric >= 0 and <= 1
  # * comparison_cases should be a numeric integer > 0
  # * comparison_n should be a numeric integer >= count
  # * all other inputs checked when dispatched to estimate_proportion

  # Check reference_p
  esci_assert_type(reference_p, "is.numeric")
  esci_assert_range(
    reference_p,
    lower = 0,
    upper = 1,
    lower_inclusive = TRUE,
    upper_inclusive = TRUE
  )




  # Figure out analysis type ---------------------------------------
  analysis_type <- "Undefined"

  # Check to see if summary data has been passed
  if (!is.null(comparison_cases)) {
    # Summary data is passed, so check to make sure raw data not included
    if(!is.null(data))  stop(
      "You have passed summary statistics,
      so don't pass the 'data' parameter used for raw data.")
    if(!is.null(outcome_variable)) stop(
      "You have passed summary statistics,
      so don't pass the 'outcome_variable' parameter used for raw data.")

    # Looks good, we can pass on to summary data

    # Check comparison_cases
    esci_assert_type(comparison_cases, "is.numeric")
    esci_assert_type(comparison_cases, "is.whole.number")
    esci_assert_range(
      comparison_cases,
      lower = 0,
      lower_inclusive = TRUE,
    )

    # Check comparison_n
    esci_assert_type(comparison_n, "is.numeric")
    esci_assert_type(comparison_n, "is.whole.number")
    esci_assert_range(
      comparison_n,
      lower = comparison_cases,
      lower_inclusive = TRUE,
    )

    analysis_type <- "summary"

  } else {
    # Raw data has been passed, first sure summary data is not passed
    if(!is.null(comparison_cases))  stop(
      "You have passed raw data,
      so don't pass the 'comparison_cases' parameter used for summary data.")
    if(!is.null(comparison_n))  stop(
      "You have passed raw data,
      so don't pass the 'comparison_n' parameter used for summary data.")

    if (is.null(data)) {
      analysis_type <- "vector"
    } else {

      is_char <- try(
        is.character(outcome_variable), silent = TRUE
      )

      if (class(is_char) == "try-error") {
        # If not a character, must have been quoted
        outcome_variable_enquo <- rlang::enquo(outcome_variable)
        outcome_variable_quoname <- try(
          eval(rlang::as_name(outcome_variable_enquo)), silent = TRUE
        )
        if (class(outcome_variable_quoname) != "try-error") {
          # This only succeeds if outcome_variable was passed unquoted
          # Reset outcome_variable to be fully quoted
          outcome_variable <- outcome_variable_quoname
          outcome_variable_name <- outcome_variable
        } else {
          stop("Could not parse outcome_variable")
        }
      }

      if (length(outcome_variable) == 1) {
        analysis_type <- "data.frame"
      } else {
        analysis_type <- "jamovi"
      }

    }


  }

  # Dispatch to estimate_proportion

  if (analysis_type == "summary") {
    if (is.null(case_label)) case_label <- "Affected"
    if (is.numeric(case_label) | case_label == 1) case_label <- "Affected"

    estimate <- estimate_proportion(
      cases = c(comparison_cases, comparison_n - comparison_cases),
      outcome_variable_name = outcome_variable_name,
      outcome_variable_levels = c(
        case_label,
        paste("Not", case_label, sep = " ")
      ),
      conf_level = conf_level,
      count_NA = count_NA
    )
  } else if (analysis_type == "vector") {
    if (outcome_variable_name == "My outcome variable") {
      outcome_variable_name <- deparse(substitute(outcome_variable))
    }

    estimate <- estimate_proportion(
      outcome_variable = outcome_variable,
      outcome_variable_name = outcome_variable_name,
      case_label = case_label,
      conf_level = conf_level,
      count_NA = count_NA
    )
  } else if (analysis_type == "data.frame") {
    estimate <- estimate_proportion(
      data = data,
      outcome_variable = outcome_variable,
      outcome_variable_name = outcome_variable_name,
      case_label = case_label,
      conf_level = conf_level,
      count_NA = count_NA
    )
  } else if (analysis_type == "jamovi") {
    estimate <- estimate_pdiff_one.jamovi(
      data = data,
      outcome_variables = outcome_variable,
      reference_p = reference_p,
      case_label = case_label,
      conf_level = conf_level,
      count_NA = count_NA
    )
    return(estimate)
  }

  # Now change to an estimated difference
  if (!is.null(estimate)) {

    # Store some info from the results ------------------
    comparison_p = estimate$es_proportion$effect_size
    case_label <- estimate$es_proportion$effect
    comparison_label <- outcome_variable_name
    reference_label <- "Reference value"
    effect_label = paste(
      outcome_variable_name,
      " \U2012 Reference value",
      sep = ""
    )

    # es_proportion_difference table ---------------------------
    estimate$es_proportion_difference <- rbind(
      estimate$es_proportion,
      estimate$es_proportion,
      estimate$es_proportion
    )
    estimate$es_proportion_difference$type <- c(
      "Comparison",
      "Reference",
      "Difference"
    )
    estimate$es_proportion_difference$effect <- c(
      comparison_label,
      reference_label,
      effect_label
    )
    estimate$es_proportion_difference[2, c("effect_size", "LL", "UL", "SE", "effect_size_adjusted", "ta_LL", "ta_UL")] <-
      c(reference_p, NA, NA, NA, NA, NA, NA)
    estimate$es_proportion_difference[3, c("effect_size", "LL", "UL", "effect_size_adjusted", "ta_LL", "ta_UL")] <-
      estimate$es_proportion_difference[3, c("effect_size", "LL", "UL", "effect_size_adjusted", "ta_LL", "ta_UL")] - reference_p


    estimate$es_proportion <- NULL
    estimate$es_proportion_properties <- NULL


    # Other properties ---------------------------
    estimate$properties$contrast <- c(1, -1)
    names(estimate$properties$contrast) <- c(
      outcome_variable_name,
      "Reference Mean"
    )
    estimate$es_proportion_difference_properties <- list(
      effect_size_name = "P_Diff",
      effect_size_name_html = "<i>P</i><sub>diff</sub>",
      effect_size_category = "difference",
      effect_size_precision = "proportion",
      conf_level = conf_level,
      error_distribution = "norm"
    )

    if ("Missing" %in% estimate$overview$outcome_variable_level) {
      estimate$es_proportion_difference_properties$message <- if (count_NA)
        "Missing values were present; these were counted as part of the total sample size."
      else
        "Missing values were present; these were *not* counted as part of the total sample size."

      estimate$es_proportion_difference_properties$message_html <- if (count_NA)
        "Missing values were present; these were counted as part of the total sample size."
      else
        "Missing values were present; these were <b>not</b> counted as part of the total sample size."

      estimate$overview_properties <- list()
      estimate$overview_properties$message <- estimate$es_proportion_difference_properties$message
      estimate$overview_properties$message_html <- estimate$es_proportion_difference_properties$message_html

    }

    return(estimate)
  }


  stop("Something went wrong dispatching this function")

}



estimate_pdiff_one.jamovi <- function(
  data,
  outcome_variables,
  reference_p = 0,
  case_label = 1,
  conf_level = 0.95,
  count_NA = FALSE
) {

  res <- list()

  # Cycle through the list of columns;
  #  for each call estimate_mean_one.data-frame, which handles 1 column
  for (outcome_variable in outcome_variables) {

    # Now pass along to the .vector version of this function
    res[[outcome_variable]] <- estimate_pdiff_one(
      data = data,
      outcome_variable = outcome_variable,
      outcome_variable_name = outcome_variable,
      reference_p = reference_p,
      case_label = case_label,
      conf_level = conf_level,
      count_NA = count_NA
    )

  }

  res <- esci_estimate_consolidate(res)
  class(res) <- "esci_estimate"

  return(res)

}
rcalinjageman/esci4 documentation built on May 18, 2023, 4:01 a.m.