Skip to contents

detect_exposure_type() reads an exposure vector and reports whether the analysis it feeds should treat it as binary, categorical, or continuous. It is the reading the r-causal packages take when a caller declares no type, so the classification lives in one place and every package that needs it gives the same answer for the same column.

Usage

detect_exposure_type(
  .exposure,
  arg = ".exposure",
  announce = TRUE,
  call = rlang::caller_env()
)

Arguments

.exposure

The exposure vector to classify.

arg

The name the announcement gives the exposure argument. A function whose exposure argument is named something else passes its own name, so the announcement never points at an argument the caller does not have.

announce

Should the detected type be announced? The announcement reports which branch the analysis took, so a caller passes FALSE where that is not worth reporting, such as one detecting several exposures at once. It is suppressed for every call, whatever this argument says, when options(causalgenerics.quiet = TRUE).

call

The environment a refusal reports as its calling context. Detection raises none of its own; the argument is here so that a caller threading its own call through the resolver passes it the same way to every part of it.

Value

A single string: "binary", "categorical", or "continuous".

Details

The reading is taken in this order. A vector with exactly two observed values is binary, whatever its type. A factor or character vector taking more than two observed values is categorical, and one taking fewer is binary, so a single-level factor is read as a degenerate binary exposure rather than as a categorical one. Any other vector is categorical when is_categorical() finds few enough distinct values in it, and continuous otherwise.

A missing value is not a level. Every count is taken over the observed values, so an exposure recorded with missing values is read as the exposure it is: two observed values are binary however many observations are missing, and a categorical exposure reports the categories it has rather than one more.

Detection classifies what it is handed and refuses nothing. An exposure with one observed value, and one with none, each leave the branches above with a type rather than an error, because what a degenerate exposure means depends on what the calling function is about to fit with it. That refusal belongs to the calling function. check_forced_type() is the structural check for a type the caller declared.

See also

match_exposure_type(), which resolves a declared type against the types a function supports and calls this when the caller asked for detection.

Examples

# Two observed values are binary, and the missing one is not a third value.
detect_exposure_type(c(0, 1, NA, 1))
#>  Treating `.exposure` as binary
#> [1] "binary"

# More than two levels are categorical.
detect_exposure_type(factor(c("low", "medium", "high")))
#>  Treating `.exposure` as categorical
#> [1] "categorical"

# A numeric exposure taking many distinct values is continuous.
detect_exposure_type(seq_len(300) / 300)
#>  Treating `.exposure` as continuous
#> [1] "continuous"

# A function whose exposure argument is named otherwise says so.
detect_exposure_type(c(0, 1), arg = ".exposures")
#>  Treating `.exposures` as binary
#> [1] "binary"

# `announce = FALSE` returns the reading without reporting it.
detect_exposure_type(c(0, 1), announce = FALSE)
#> [1] "binary"