---
title: "quadratic effects"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{quadratic effects}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
EVAL_DEFAULT <- FALSE
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  eval = EVAL_DEFAULT
)
```

```{r setup}
library(modsem)
```
# Quadratic Effects and Interaction Effects

Quadratic effects are essentially a special case of interaction effects—where a variable interacts with itself. As such, all of the methods in `modsem` can also be used to estimate quadratic effects.

Below is a simple example using the `LMS` approach.

```{r}
library(modsem)
m1 <- '
# Outer Model
X =~ x1 + x2 + x3
Y =~ y1 + y2 + y3
Z =~ z1 + z2 + z3

# Inner model
Y ~ X + Z + Z:X + X:X
'

est1_lms <- modsem(m1, data = oneInt, method = "lms")
summary(est1_lms)
```

In this example, we have a simple model with two quadratic effects and one interaction effect. We estimate the model using both the `QML` and double-centering approaches, with data from a subset of the PISA 2006 dataset.

```{r}
m2 <- '
ENJ =~ enjoy1 + enjoy2 + enjoy3 + enjoy4 + enjoy5
CAREER =~ career1 + career2 + career3 + career4
SC =~ academic1 + academic2 + academic3 + academic4 + academic5 + academic6
CAREER ~ ENJ + SC + ENJ:ENJ + SC:SC + ENJ:SC
'

est2_dca <- modsem(m2, data = jordan)
est2_qml <- modsem(m2, data = jordan, method = "qml")
summary(est2_qml)
```

**NOTE**: We can also use the LMS approach to estimate this model, but it will be a lot 
slower, since we have to integrate along both `ENJ` and `SC`. In the first example 
it is sufficient to only integrate along `X`, but the addition of the `SC:SC` term
means that we have to explicitly model `SC` as a moderator. This means that 
we (by default) have to integrate along `24^2=576` nodes. This both affects the 
the optimization process, but also dramatically affects the computation time of 
the standard errors. To make the estimation process it is possible to reduce the number
of quadrature nodes, and calculate standard errors using the outer product of the
score function, instead of the negative of the hessian matrix. Additionally, we can
also pass `mean.observed = FALSE`, constraining the intercepts of the indicators to zero.

```{r}
m2 <- '
ENJ =~ enjoy1 + enjoy2 + enjoy3 + enjoy4 + enjoy5
CAREER =~ career1 + career2 + career3 + career4
SC =~ academic1 + academic2 + academic3 + academic4 + academic5 + academic6
CAREER ~ ENJ + SC + ENJ:ENJ + SC:SC + ENJ:SC
'

est2_lms <- modsem(m2, data = jordan, method = "lms", 
                   nodes = 15, OFIM.hessian = FALSE, 
                   mean.observed = FALSE)
summary(est2_lms)
```