Hello all,
I have a very rich dataset composed of observational communications (e.g. email data), psychometric surveys, and individual outcomes (e.g. salary, performance reviews). And it’s all recorded on two different occasions 12 months apart. My hypotheses are centered on “change predicts change”. That is a change in the communication network should be associated with some change in individual outcomes.
To estimate the effects of change of one variable on the change of another another variable from one occasion to the next, I’ve been using a Latent Difference Score estimated using lavaan. This has served pretty well, except it has some pretty substantial limitations. For one it’s difficult to estimate interactions in structural equation models. Also I want to estimate different effects for each division in the organization, which implies a multi-level model, but lavaan isn’t well-suited for this. For now I’ve been splitting the sample, but I don’t like that approach.
Here is a discussion of latent difference scores here for further reading:
Gollwitzer, M., Christ, O., & Lemmer, G. 2014. Individual differences make a difference: On the use and the psychometric properties of difference scores in social psychology. European Journal of Social Psychology , 44(7): 673–682.
And this is a figure of the model. The latent “delta” is the estimated latent difference score.
Here is some simulated example data.
set.seed(42)
N <- 100
x1 <- rnorm(N, mean = 3, sd = 1)
d <- tibble(id = 1:N, x1 = x1)
d$x2 <- d$x1 + rnorm(N, mean = 3.2, sd = 1)
d$sx <- NA_real_
In lavaan specifying this model is straightforward. The sx is the latent difference score (slope of x).
library(lavaan)
m1 <- '# set the autoregressive path to 1
x2 ~ 1 * x1
# define the latent variable
sx =~ 1 * x2
# means (no mean for the non-baseline exogenous covariates)
sx ~ 1
x1 ~ 1
x2 ~ 0
# exogenous covariances
x1 ~~ x1 + sx
sx ~~ sx
# disturbances set to 0
x2 ~~ 0 * x2
'
f1_lv <- lavaan(m1, d, fixed.x=F)
summary(f1_lv)
This fits well. Then you can estimate an LDS for each measure. Then create a structural model of the different paths between the estimated LDS to test the hypotheses.
> mean(predict(f1_lv)[,'sx'])
[1] 3.112516
When I try to translate this in to brms, I don’t have the same success.
f1_formula <- bf(x2 ~ mi(sx) + x1 + 0) +
bf(x1 ~ 1) +
bf(sx | mi() ~ 1 + x1) +
set_rescor(rescor = FALSE)
get_prior(f1_formula, data = d)
f1_prior <- prior(constant(1), resp = 'x2', coef = 'x1') +
prior(constant(1), resp = 'x2', coef = 'misx') +
prior(normal(0, 0.001), resp = 'x2', class = 'sigma')
f1 <- brm(formula = f1_formula,
prior = f1_prior,
data = d)
mcmc_plot(f1)
I’m asking if anyone has a good idea of how to translate the lavaan code to brms (or RStan, if I can have to learn the low-level code, I guess this is a good time to get started).
Alternatively, is there a better way to examine these hypotheses? Does change predict change?
For instance here’s another simulated dataset of two variables. In this case the change in x impacts the change in y. A bigger change in x causes a bigger change in y. How would you model something like this?
Thank you much for reading!
set.seed(42)
# 100 subjects
N <- 100
d <- tibble(id = 1:N,
x1 = rnorm(N, mean = 3, sd = 1)) %>%
mutate(x2 = x1 + rnorm(N, mean = 1, sd = 1)) %>%
mutate(xdiff = x2 - x1) %>%
mutate(y1 = rnorm(N, mean = 3, sd = 1)) %>%
mutate(y2 = y1 + rnorm(N, mean = xdiff, sd = 1)) %>%
select(-xdiff) %>%
gather('k', 'value', -id) %>%
mutate(variable = map_chr(str_split(k, pattern = ''), 1)) %>%
mutate(time = map_chr(str_split(k, pattern = ''), 2)) %>%
select(-k) %>%
spread(variable, value)
> glimpse(d)
Observations: 200
Variables: 4
$ id <int> 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 1…
$ time <chr> "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "…
$ x <dbl> 4.370958, 6.571924, 2.435302, 4.480053, 3.363128, 3.359920, 3.632863, 6…
$ y <dbl> 0.9990708, 3.1954154, 3.3337772, 6.1387705, 4.1713251, 4.2071074, 5.059…