I was tagged today on twitter asking about categorical variables in `lavaan`

. I will say I have not done much with categorical predictors either endogenous or exogenous. I did a quick reproducible example of exogenous variables, and I will refer you to the help guide for `lavaan`

here.

You will need both the `lavaan`

and `psych`

packages to reproduce this code. Ironically, this data is binary outcome data (the `epi`

dataset in `psych`

), which wasn’t intentional, I just knew it was a good dataset to work with to test how to do exogenous categorical variables.

First, let’s make a model that works (I do assume you know a bit about `lavaan`

here, feel free to ask questions):

```
#load libraries and data
library(psych)
library(lavaan)
DF = epi
#lavaan model syntax
epi.model = 'latent =~ V1+V2+V3+V4
latent2 =~ V5+V6+V7+V8'
#analyze the model
epi.fit = cfa(model = epi.model,
data = DF)
#show a summary
summary(epi.fit)
```

The `cfa`

and `summary`

did not throw any errors, so the model at least runs smoothly, even if it is not a “good” model. For good measure, you can also use `semPlot`

to create a picture of this two-factor model:

```
library(semPlot)
#semPaths with basic options
semPaths(epi.fit,
whatLabels = "std",
edge.label.cex = 1)
```

Next, I created a fake dummy coded variable with three levels, although you could scale this easily with more levels:

```
DF$category = c(rep("group", nrow(epi)/3),
rep("group2", nrow(epi)/3),
rep("group3", nrow(epi)/3))
DF$category = as.factor(DF$category)
```

When I tried to run a new model with the `category`

variable, `lavaan`

was not happy:

```
Warning message:
In lav_data_full(data = data, group = group, cluster = cluster, :
lavaan WARNING: unordered factor(s) with more than 2 levels detected in data: category
```

Fine, let’s dummy code them with the gloriously easy `dummy.code`

function in `psych`

:

```
#dummy code and combine with DF
DF_dc = cbind(DF, dummy.code(DF$category))
```

However, I will warn you that `psych`

does give you K columns where K = levels. Real dummy coding is K - 1 columns, so I find it odd that `psych`

gives you K output. For example, it took our `group`

, `group2`

, `group3`

labels and transformed them into three new columns with 0 as *not my group* and 1 as *my group*. Therefore, I will advise you to pick your favorite combination of K - 1 levels, and do not use all of them or you will create a singular matrix that will be difficult to troubleshoot in any regression based analysis. Here’s an example of that error:

```
Error in lav_samplestats_icov(COV = cov[[g]], ridge = ridge, x.idx = x.idx[[g]], :
lavaan ERROR: sample covariance matrix is not positive-definite
```

I can add the first two to the model predicting one of the latents using `~`

for regression rather than `=~`

for create a latent:

```
#model syntax
epi.model2 = 'latent =~ V1+V2+V3+V4
latent2 =~ V5+V6+V7+V8
latent ~ group
latent ~ group2'
#analyze the model with the new DF
epi.fit2 = cfa(model = epi.model2,
data = DF_dc)
#summarize the model
summary(epi.fit2)
```

In your output, you will get two new lines for regression:

```
Regressions:
Estimate Std.Err z-value P(>|z|)
latent ~
group 0.026 0.014 1.847 0.065
group2 -0.001 0.014 -0.082 0.935
```

The interpretation here would be that group = group 1 versus group 3 was related to/predicted `latent`

at 0.026, so the difference in `latent`

for group 1 to group 3 was 0.026. The second variable would be group2 = group 2 versus group 3, and they basically have no difference on `latent`

. You can learn more about dummy coding here.

Here’s the picture of that analysis:

```
semPaths(epi.fit,
whatLabels = "std",
edge.label.cex = 1)
```

Remember that any endogenous variables will get automatically correlated … so now we have a second latent variable hanging out in space we would want to either predict with our dummy coded variables or do something with. So, I would probably either add the correlation between latents back in with: `latent ~~ latent2`

or add in the regressions for using the categoricals to predict latent2: `latent2 ~ group`

and `latent2 ~ group2`

.

More lavaan help can be found on my youtube channel!.