---
title: "Gene Environment Interaction (GxE) Genome Wide Association Study"
output:
  rmarkdown::html_vignette:
    self_contained: false
vignette: >
  %\VignetteIndexEntry{GxE GWAS}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
is_CRAN <- !identical(Sys.getenv("NOT_CRAN"), "true")
knitr::opts_chunk$set(eval = !is_CRAN)
```

Gene-environment interaction (GxE) studies are incredibly popular methods to explore the potential for varying levels of genetic sensitivity in different environments. On a broad level, antecedents and consequences that make specific genetic variants differentially sensitive to environmental stimuli inform numerous phenomena, such as evolutionary pressures and epigenetic effects.

***

Example

To demonstrate how to conduct a GxE GWAS using GW-SEM, we use simulated data for a one factor GWAS model with 6,000 individuals consisting of 2,000 SNPs, three correlated items and 6 covariates (that are a proxy for age, sex, ancestry principle components or other confounds). We simulated similar data that we use in this demonstration.

***

The first step is opening R, and loading the GW-SEM package as well as the phenotypic data (including the dependent variable, the moderating/interacting variable and any covariates such as age, sex, or ancestry principle components) into the R computing environment. This can be achieved by using the command below:

```{r}
library(gwsem)

location <- 'https://jpritikin.github.io/gwsem/gwsemGxEexample'

# Read the phenotype data into R and look at the data
gxeData <- read.table(file.path(location, "gxeData.txt"), header=TRUE)
```

Once the data are loaded into R, you can recode the data, transform it, and tell R if we have ordinal or binary indicators using `mxFactor()`. The data for this example are simulated and continuous, and therefore, we will not be doing anything now, but if you would like to chop the indicators up into binary or ordinal variables, this is when you would do it. It is possible to conduct GxE analyses on binary or ordinal variables. With GW-SEM we assume that the binary or ordinal variable follows the Liability-Threshold Model (where the observed categories reflect portions of the underlying liability distribution).

Once you are satisfied the data are in the appropriate shape we can build a one factor GWAS model with the following command: 

```{r} 
gxe <- buildItem(phenoData = gxeData, depVar  = "phe",
                  covariates = c("mod", "snp_mod" ,"pc1", "pc2", "pc3", "pc4","pc5"),
                  fitfun = "WLS", exogenous = T, gxe = "mod")
```

There are a few differences in how the GxE GWAS is specified relative to the standard GWAS even though both models use the _**buildItem**_ function.  First, we must add the **_gxe_** argument which tells GW-SEM that we want to conduct a GxE GWAS and which variable is the moderator.  By doing so, when GW-SEM reads in the GWAS data in the C++ backend, it will automatically create a multiplicative interaction variable. This newly created variable name will be named "snp" with your specific variable name appended to it, separated by an underscore. In the current example, our moderating variable is named "mod" and therefore the interaction term is named "snp_mod". If your variable name was "environment" then the interaction term would be labeled "snp_environment".  Second, we must add this newly created variable to the list of covariates by including the label for the newly created interaction variable.  Finally, it is strongly suggested that you use the **_exogenous = T_** argument. Otherwise, the standard errors of the interaction component tend to be substantially higher than those in comparable OLS regression models.

After you have built the gxe model and put it into an object (named gxe), you can take this object which is technically an OpenMx model, and fit it using **_mxRun()_**

```{r}
gxeFit <- mxRun(gxe)
summary(gxeFit)
```

It is strongly advised to test out the model, as it is a great time to make sure that your model is specified as expected. Provided that the model looks reasonable, you can pass the model into the `GWAS` function,

```{r}
library(curl)
curl_download(file.path(location, 'example.pgen'),
              file.path(tempdir(),'example.pgen'))
curl_download(file.path(location, 'example.pvar'),
              file.path(tempdir(),'example.pvar'))

GWAS(model = gxe,                            # the model object
	snpData = file.path(tempdir(), 'example.pgen'),            # the path to the snpData
	out=file.path(tempdir(), "gxe.log"))                       # the results file name

```

When you execute this command, you will begin running your GWAS.  

After you finish running the GWAS analysis, the next step is to read the results into R so that you can examine them, plot them, prepare them for used by other software packages, etc. While you are unlikely to want to read all of the output into R, it is useful to do this on a small test GWAS analysis to ensure that you are getting reasonable results. To do so, you can use the base R function **_read.delim_**.  This is didactically useful, but it contains much more information than most people want

```{r}
gxeResult <- read.delim(file.path(tempdir(), "gxe.log"))                            
```

More reasonably, we will want to examine the results for a specific parameter using the _**loadResults**_ function. This function takes takes two arguments: the path to the data and the column name from the results file for the parameter that you want to examine. Once the summary statistics have been read into R, it is possible to manipulate the results using standard R commands, such as sorting the results by Z-statistics or P-values, as shown below:


```{r}
succinctCond <- loadResults(path = file.path(tempdir(), "gxe.log"), focus =  "snp_to_phe")
succinctInt  <- loadResults(path = file.path(tempdir(), "gxe.log"), focus =  "snp_mod_to_phe")

head(succinctCond[order(succinctCond$Z, decreasing = T),])
head(succinctInt[order(succinctInt$Z, decreasing = T),])

```

We can also read in the marginal effects for a specific level of the environment, as well as their standard errors, z-statistics, and p-values. To do this, we can use the **_loadResults_** command and specify the **_moderatorLevel_** argument with a numerical value. In the current case, the standard deviation of the moderator variable is 1, by using values of -2 and 2, we are asking GW-SEM to provide the marginal effects for 2 standard deviations below and above the means.  While any value of the moderator can be requested, we would suggest using reasonable values of the moderating variable.

```{r}
margLow  <- loadResults(path = file.path(tempdir(), "gxe.log"), focus =  "snp_mod_to_phe", moderatorLevel= -2)
margHigh <- loadResults(path = file.path(tempdir(), "gxe.log"), focus =  "snp_mod_to_phe", moderatorLevel=  2)

```

Now that we have the various components that contribute to our GxE GWAS model, we can begin constructing Manhattan plots for the relevant parameters. 

```{r}
# Manhattan Plots for directly estimated parameters
plot(succinctCond)  # To plot p-values of the conditional effect
plot(succinctInt)   # To plot the interaction coefficient

# Manhattan Plots for marginal effects
plot(margLow)    # To plot p-values for a low level (-2SD) of the moderator
plot(margHigh)   # To plot p-values for a high level (+2SD) of the moderator

```

As GxE GWAS methods are under-utilized in the literature, consensus about how these results should be presented is developing.  When interpreting and presenting the results, therefore, it is imperative that the each specific parameter is interpreted correctly.  For example, while most people call the parameter from the SNP to the phenotype the "Main Effect", it is better thought of as a conditional effect as strictly speaking it is the association between the SNP and the phenotype under the specific condition where the environment is equal to zero and not the average effect of the SNP across all levels of the environment as would be implied by the term _main effect_.  By contrast, the interaction parameter is the difference in the SNP association between when the environment is equal to zero and when the environment is equal to one.

An alternative, and preferable, interpretation of the GxE GWAS model is to calculate what we call Marginal Effects (or Simple Slopes).  This is done automatically by GW-SEM using the **_TODO_** functions.  Marginal effects can be interpreted as the GWAS coefficients at a particular level of the environment.  For example, if the moderator is binary (e.g., for sex) we could calculate the GWAS results for either Males (sex = 0) or females (sex = 1). Alternatively, if the moderator is continuous (e.g.,, age) we might want to calculate the GWAS results for a low level of the moderator (2 SD below the moderator mean) and a high level of the moderator (2 SD above the moderator mean), or at some other particularly relevant value. Notably, while the calculation of marginal effects is an additional step in the analytical process (that GW-SEM does automatically), marginal effects are often more interpretable than either the conditional or interaction parameters, as well as being more closely related to the hypothesis that the analyst is trying to test.
