Skip to contents

Simulates a long-format dataset from the generic (unit, observation, trait) stacked-trait GLLVM that the package supports. A unit is any grouping over which a between-unit covariance structure applies (individual, site, species, paper, ...) and each unit carries n_obs_per_unit within-unit observations: $$y_{uot} = \alpha_t + b_{ut} + w_{uot} + e_{uot}$$ where \(b_{ut}\) is the between-unit signal (reduced-rank Lambda_B plus diagonal psi_B), \(w_{uot}\) the within-unit observation-level signal (reduced-rank Lambda_W plus diagonal psi_W), and \(e_{uot}\) a row-level residual.

Usage

simulate_unit_trait(
  n_units = 50L,
  n_obs_per_unit = 3L,
  n_traits = 5L,
  alpha = NULL,
  Lambda_B = NULL,
  Lambda_W = NULL,
  psi_B = NULL,
  psi_W = NULL,
  sigma2_eps = 0.5,
  seed = NULL,
  ...
)

Arguments

n_units

Integer; number of units \(U\).

n_obs_per_unit

Integer; number of within-unit observations \(O\) per unit.

n_traits

Integer; number of traits \(T\).

alpha

Optional length-n_traits vector of trait intercepts; random if NULL.

Lambda_B

Optional n_traits x d_B between-unit loading matrix for the reduced-rank between-unit component. Set to NULL (default) to omit.

Lambda_W

Optional n_traits x d_W within-unit loading matrix for the reduced-rank observation-level component (matching a default latent() term, or an explicit latent(unique = TRUE) term, on the within-unit grouping). Set to NULL (default) to omit.

psi_B

Optional length-n_traits vector of trait-specific between-unit variances. (Lowercase psi matches the factor-analysis convention – \boldsymbol\Psi_B = diag(psi_B); see decisions.md 2026-05-14 notation reversal.)

psi_W

Optional length-n_traits vector of trait-specific within-unit (observation-level) variances – \boldsymbol\Psi_W = diag(psi_W).

sigma2_eps

Row-level residual variance. Default 0.5.

seed

Optional RNG seed.

...

Reserved for future extensions; currently ignored.

Value

A list with components:

data

Long-format data frame with one row per (unit, observation, trait): columns unit, observation, trait, value, and unit_observation – the row id used for a per-observation diagonal within-unit grouping (one level per unit-observation cell).

truth

Named list of true parameter values: alpha, Lambda_B, Lambda_W, psi_B, psi_W, sigma2_eps.

Details

This is the generic sibling of simulate_site_trait(). Use this function when the design is an abstract (unit, observation, trait) layout with no phylogenetic or spatial structure. Use simulate_site_trait() when you need the domain-specific functional-biogeography (site, species, trait) cube with phylogenetic species correlation and spatial site coordinates baked into the DGP.

Each component can be turned on or off via the corresponding variance / loading argument. The all-NULL default settings produce a fixed-effects-only dataset (trait intercepts plus row-level residual) suitable for fast regression fixtures.

See also

simulate_site_trait() for the domain-specific (site, species, trait) functional-biogeography simulator with phylogenetic and spatial machinery.

Examples

set.seed(1)
## Fixed-effects-only default (all structure NULL):
sim0 <- simulate_unit_trait(n_units = 20, n_obs_per_unit = 3, n_traits = 4)
head(sim0$data)
#>   unit observation   trait       value unit_observation
#> 1    1           1 trait_1 -0.39345663              1_1
#> 2    1           1 trait_2 -0.39651543              1_1
#> 3    1           1 trait_3 -0.49096422              1_1
#> 4    1           1 trait_4  2.11735521              1_1
#> 5    1           2 trait_1 -0.21931491              1_2
#> 6    1           2 trait_2 -0.03229888              1_2
sim0$truth$alpha
#> [1] -0.6264538  0.1836433 -0.8356286  1.5952808

## With a between-unit reduced-rank loading and diagonal within-unit term:
Lambda_B <- matrix(c(0.9, 0.7, -0.4, 0.2,
                     0.1, -0.2, 0.6, 0.8), nrow = 4, ncol = 2)
sim <- simulate_unit_trait(n_units = 40, n_obs_per_unit = 3, n_traits = 4,
                           Lambda_B = Lambda_B, psi_W = 0.3, seed = 1)
str(sim$truth)
#> List of 6
#>  $ alpha     : num [1:4] -0.626 0.184 -0.836 1.595
#>  $ Lambda_B  : num [1:4, 1:2] 0.9 0.7 -0.4 0.2 0.1 -0.2 0.6 0.8
#>  $ Lambda_W  : NULL
#>  $ psi_B     : NULL
#>  $ psi_W     : num [1:4] 0.3 0.3 0.3 0.3
#>  $ sigma2_eps: num 0.5