Skip to contents

Get data for one-sample or dependent two-sample tests using a formula. Three forms are supported.

  • y ~ x | z

  • y ~ x

  • ~x

Usage

get_dep_data(data, formula, allow_one_sample = TRUE, agg_fun = "error")

Arguments

data

(data.frame)
The data frame containing the formula variables.

formula

(formula)
The formula to be parsed and evaluated on the data.

allow_one_sample

(scalar logical: TRUE)
Whether or not a formula of form ~x is allowed.

agg_fun

(Scalar character or function: "error")
Used for aggregating duplicate cases of grouping/blocking combinations when formula of form y ~ x | z is used. Ignored with a warning when the formula has no block term. Select one of "first", "last", "sum", "mean", "median", "min", or "max" for built-in aggregation handling (each applies na.rm = TRUE). Or define your own function. User-defined functions are routed through a generic aggregator that is slower than the built-in cases. "error" (default) will return an error if duplicate grouping/blocking combinations are encountered.

Value

A named list with components:

  1. data

    The response values split by group. For ~x a length-1 named list holding the outcome vector. For y ~ x a length-2 named list with the focal group first and the reference group second. For y ~ x | z a data.frame with the focal group in column 1, the reference group in column 2, and the block identifier in column 3, with one row per level of the block factor in levels(z) order.

  2. focal_group

    A scalar character naming the focal group. The name of the response variable for y ~ x, the single term for ~ x, or the second factor level for y ~ x | z.

  3. ref_group

    A scalar character naming the reference group, or NULL for a ~x formula. The name of the grouping variable for y ~ x, or the first factor level for y ~ x | z.

  4. block

    A scalar character naming the block column for y ~ x | z, or NULL otherwise.

  5. parse_formula

    The list returned by parse_formula() applied to formula.

Details

Dependent two-sample tests

For dependent two-sample tests with data in tall format, the formula with form y ~ x | z is defined by

  • y is a numeric vector for the outcome.

  • x is a factor with exactly two observed levels representing the binary group variable.

  • z is a factor with n levels representing the blocking variable (subject/item index).

For factor x, the first observed level will be the reference group. For example, data$x <- factor(data$x, levels = c("pre", "post")) makes pre the reference group and post the focal group. A downstream comparison then takes the form mean(post - pre).

A non-factor x or z is converted with as.factor() and a warning is emitted. as.factor() then orders the levels alphabetically or numerically, so the reference group for x becomes its smallest value. Pass x as a factor to control which group is the reference. Declared-but-unobserved levels of x and z are dropped before the two-level check, so they cannot displace observed levels or seed all-NA rows or columns in the wide output.

For dependent two-sample tests with data in wide format, the formula with form y ~ x is defined by

  • y is a numeric vector for the group of interest.

  • x is a numeric vector for the reference group.

  • Row i of y and row i of x correspond to the same subject/item.

For returned object out, downstream differences would take the form out$data[[out$focal_group]] - out$data[[out$ref_group]].

One-sample (or paired) tests

For one-sample (or paired) tests, the formula has form ~x where

  • x is a numeric vector for the outcome (or differences).

NA handling

For ~x and y ~ x, missing values are retained and returned as-is. For y ~ x | z, a row with a missing value of x or z is dropped before reshaping. Missing values of x are ignored when checking that it has exactly two observed levels. See tall_to_wide() for missing value handling during cell-aggregation. A missing value of y is retained. A cell with no observation in the wide output becomes NA_real_.

Wrapping terms in I()

Any term in the formula may be wrapped in I(). Operators such as + and * carry special meaning inside a formula. Any other expression, such as log(y) or x > 0, must be wrapped in I() so it is evaluated as ordinary R code against data. On the left hand side, I() transforms the outcome and must yield a numeric result. For example, I(log(y)) ~ x | z uses the log-transformed outcome. On the group side, I() derives the group term. For example, y ~ I(x > 0) | z groups by whether x is positive. On the block side, I() derives the block term. For example, y ~ x | I(interaction(subject, session)) blocks by a subject-session combination.

Examples

#----------------------------------------------------------------------------
# get_dep_data() example
#----------------------------------------------------------------------------
library(bkmodel)

# A pre/post intervention study where each subject is measured twice
# pre is the first factor level, so it is the reference group
tall <- data.frame(
  score = c(5.1, 6.3, 5.8, 7.2, 6.4, 7.1, 6.9, 8.0),
  time = factor(
    rep(c("pre", "post"), times = 4),
    levels = c("pre", "post")
  ),
  subject = factor(rep(1:4, each = 2))
)

# Reshape tall data to one row per subject with focal and reference columns
res <- get_dep_data(data = tall, formula = score ~ time | subject)
res
#> $data
#>   post pre subject
#> 1  6.3 5.1       1
#> 2  7.2 5.8       2
#> 3  7.1 6.4       3
#> 4  8.0 6.9       4
#> 
#> $focal_group
#> [1] "post"
#> 
#> $ref_group
#> [1] "pre"
#> 
#> $block
#> [1] "subject"
#> 
#> $parse_formula
#> $parse_formula$formula
#> score ~ time | subject
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$lhs
#> ~score
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$rhs
#> ~time | subject
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$rhs_group
#> ~time
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$rhs_block
#> ~subject
#> <environment: 0x5ed28e9cacf0>
#> 
#> 

# Extract the paired vectors with the returned group names
focal <- res$data[[res$focal_group]]
reference <- res$data[[res$ref_group]]

# Estimate the intervention effect as the mean within-subject difference
mean(focal - reference)
#> [1] 1.1

# The same pairing feeds a paired t-test
t.test(focal, reference, paired = TRUE)
#> 
#> 	Paired t-test
#> 
#> data:  focal and reference
#> t = 7.473, df = 3, p-value = 0.004962
#> alternative hypothesis: true mean difference is not equal to 0
#> 95 percent confidence interval:
#>  0.6315566 1.5684434
#> sample estimates:
#> mean difference 
#>             1.1 
#> 

# The same study already pivoted to one row per subject
wide <- data.frame(
  post = c(6.3, 7.2, 7.1, 8.0),
  pre = c(5.1, 5.8, 6.4, 6.9)
)
get_dep_data(data = wide, formula = post ~ pre)
#> $data
#> $data$post
#> [1] 6.3 7.2 7.1 8.0
#> 
#> $data$pre
#> [1] 5.1 5.8 6.4 6.9
#> 
#> 
#> $focal_group
#> [1] "post"
#> 
#> $ref_group
#> [1] "pre"
#> 
#> $block
#> NULL
#> 
#> $parse_formula
#> $parse_formula$formula
#> post ~ pre
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$lhs
#> ~post
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$rhs
#> ~pre
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$rhs_group
#> ~pre
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$rhs_block
#> NULL
#> 
#> 

# Pre-computed within-subject differences for a one-sample test
diffs <- data.frame(
  change = c(1.2, 1.4, 0.7, 1.1)
)
get_dep_data(data = diffs, formula = ~change)
#> $data
#> $data$change
#> [1] 1.2 1.4 0.7 1.1
#> 
#> 
#> $focal_group
#> [1] "change"
#> 
#> $ref_group
#> NULL
#> 
#> $block
#> NULL
#> 
#> $parse_formula
#> $parse_formula$formula
#> ~change
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$lhs
#> NULL
#> 
#> $parse_formula$rhs
#> ~change
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$rhs_group
#> ~change
#> <environment: 0x5ed28e9cacf0>
#> 
#> $parse_formula$rhs_block
#> NULL
#> 
#>