https://github.com/tysonstanley/connectivity
Tools to Assess Brain Connectivity via Granger-Causation Type Approaches (via Linear Mixed Effects Regression)
https://github.com/tysonstanley/connectivity
Last synced: 2 months ago
JSON representation
Tools to Assess Brain Connectivity via Granger-Causation Type Approaches (via Linear Mixed Effects Regression)
- Host: GitHub
- URL: https://github.com/tysonstanley/connectivity
- Owner: TysonStanley
- Created: 2019-03-28T22:17:07.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2020-03-09T22:35:44.000Z (about 5 years ago)
- Last Synced: 2025-01-24T18:12:01.508Z (4 months ago)
- Language: R
- Homepage:
- Size: 8.54 MB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.Rmd
Awesome Lists containing this project
README
---
output: github_document
---```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "60%"
)devtools::load_all("~/Dropbox/GitHub/Connectivity")
```# `connectivity` `v`r packageVersion("connectivity")``
The goal of connectivity is to make the importing/cleaning, analyzing, and visualizing of NIRS data recipe based. That is, we will use a simple recipe to take our individual NIRS files and make clear, concise analyses with interpretable output. Our approach uses a Granger-Causality-type approach using linear mixed effects models.
## Installation
You can install the GitHub version of `connectivity` with:
``` r
remotes::install_github("tysonstanley/connectivity")
```## Example
The receipe is as follows:
1. Import and Clean (`import_nirs()`)
2. Analyze (`get_connectivity()`)
3. Visualize (`effectsize_viz()` or `brain_viz()`)### Step 1. Import and Clean
The `import_nirs()` function depends on a files structure that looks something like:
```{r, echo = FALSE, eval = FALSE}
## quick-and-dirty ersatz Unix tree command in R
## inspired by this one-liner:
## ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'
## found here (among many other places):
## http://serverfault.com/questions/143954/how-to-generate-an-ascii-representation-of-a-unix-file-hierarchytwee <- function(path = getwd(), level = Inf) {
fad <-
list.files(path = path, recursive = TRUE,no.. = TRUE, include.dirs = TRUE)fad_split_up <- strsplit(fad, "/")
too_deep <- lapply(fad_split_up, length) > level
fad_split_up[too_deep] <- NULL
jfun <- function(x) {
n <- length(x)
if(n > 1)
x[n - 1] <- "|__"
if(n > 2)
x[1:(n - 2)] <- " "
x <- if(n == 1) c("-- ", x) else c(" ", x)
x
}
fad_subbed_out <- lapply(fad_split_up, jfun)
cat(unlist(lapply(fad_subbed_out, paste, collapse = "")), sep = "\n")
}
twee("~/Box/Stuttering Writing Group/PhoneCallsStutter/", level = 2)
```
```
-- P07
|__onset.txt
|__P07_brodExtract.csv
|__P07_HBA_Probe1_Oxy.csv
|__P07_HBA_Probe2_Oxy.csv
-- P08
|__onset.txt
|__P08_brodExtract.csv
|__P08_HBA_Probe1_Oxy.csv
|__P08_HBA_Probe2_Oxy.csv
-- P09
|__onset.txt
|__P09_brodExtract.csv
|__P09_HBA_Probe1_Oxy.csv
|__...
```where each participant has its own folder with the data within that folder. Other files can be within the individual folders, but the ones shown are required.
In our data (not currently provided), we have 5 regions that we are interested in that are mapped out in the `*brod.csv` files. To inform on what region goes with which channel from the Probe files, we use the import function like so:
```{r, message = FALSE, warning = FALSE}
library(connectivity)path <- "~/Box/Stuttering Writing Group/PhoneCallsControl/"
data <- import_nirs(path,
stg = 22, ipl = c(39, 40), ifg = c(44, 45), sma = 6, m1 = 4)
```where we are interested in the following regions:
- Superior Temporal Gyrus (STG),
- Inferior Parietal Lobule (made up of Supramarginal Gyrus and Angular Gyrus),
- Inferior frontal Gyrus (IFG),
- Supplementary Motor Association (SMA) and
- the Motor Cortex (M1).The `stg = 22, ipl = c(30, 40), ...` correspond to regions (the name of the region) and the number refers to the number in the `*brod.csv` file. This creates a nested tibble called `data` that looks like this:
```{r}
data
```The `probe_data` variable contains all the NIRS information about the corresponding participant. We need to make sure that the data still have the "regions" attribute with the names of the regions that you are interested in. This information is used in the next step.
```{r}
## Subset the data to just resting and assign to `rest`
rest <- data
rest$probe_data = purrr::map(rest$probe_data, ~.x %>% filter(task == "rest"))
## Make sure `rest` still contains information on the regions in the data
attr(rest, "regions")
```### Step 2. Analyze
From here, we can do our connectivity analyses, which will run a series of linear mixed effects models. If we specify a group variable, the models will include a region by group interaction. Here, we are only going to use the "resting" task for these analyses (that we created above). The `get_connectivity()` function runs the linear mixed models and provides us with a tibble where it shows us our outcome (`outcome`), the predictor region (`rowname`), the effect size estimate (`est`), and the p-value (`pvalue`).
```{r}
fits <- get_connectivity(rest, covariates = c("(1 | participant)"))
fits
```In this case, this `fits` object has all the estimates from the various models and their corresopnding p-values (based on Satterthwaite approximation to degrees of freedom). The `est` variable shows us the effect size for each variable. This effect size is the average individuals standardized coefficient (similar to a partial correlation). (Note that `lag` is the 1 lag of the outcome variable and so its effect sizes will almost always be really big and is generally not of direct interest).
### Step 3. Visualize
We can visualize these results in two main ways:
1. Simple graphs highlighting the effect size
2. Brain visualization where the various regions are mapped onto a diagram of a brainHere, we quickly show both.
Notably, both approaches use `ggplot2` and can be adjusted with `ggplot2` functions.
#### Effect Size Graphs
This shows the size of the effects as simple line graphs as shown below.
```{r}
effectsize_viz(fits)
```#### Brain Visualization
The brain visuals are the most flexible visualization. At its simplest, it shows the regions of interest on the side view of the brain.
```{r}
brain_viz(fits)
```To control the colors of the circles and lines, use any of the ggplot2 `scale_color_*` functions and remove unnecessary legends with `theme()`:
```{r}
brain_viz(fits) +
scale_color_viridis_d() +
theme(legend.position = "none")
```You can also color the lines based on other information. For example, we may want to color the lines based on whether it is bigger than some specified effect size. To do this, we will create a data frame from the `fits` object from `get_connectivity()` function.
```{r}
coloring <- fits %>%
mutate(coloring = case_when(est > .001 ~ 1,
est <= .001 ~ 0) %>% factor())brain_viz(fits, colors = coloring) +
scale_color_viridis_d() +
theme(legend.position = "none")
```For these brain visuals, there is a built-in list of regions with corresponding `x` and `y` values that fit this diagram.
```{r}
connectivity::regions_side
```However, if you want to add your own, you can. You need to make sure the names you give the regions in the `import_nirs()` function matches the names in the regions and that this `regions` data frame has the names `x`, `y`, and `region`. For example, let's say we are only interested in three of these regions now. We could use the following `regs` data frame to adjust not only what is shown but where they are shown. Importantly, the values for the `x` and `y` are bound between 0 and 10 (0 being the left/bottom and 10 being right/top) and so this example is extreme.
```{r}
regs <- tibble::tribble(
~x, ~y, ~region,
1, 1, "stg",
5, 9, "ipl",
9, 1, "ifg"
)brain_viz(fits, regs = regs)
```In addition to this side diagram (`view = "side"`), the other built-in images include a top view (`view = "top"`), an angled left side (`view = "left"`), and an angled right side (`view = "right"`). ^[Note that the `view = "top"` has functionality that allows each probe to be different sides of the brain.]
```{r, echo = FALSE, message = FALSE, warning = FALSE, fig.width=6, fig.height=6}
d1 <- import_nirs("~/Box/Stuttering Writing Group/PhoneCallsStutter/",
dlpfc_left = 22, dlpfc_right = 39,
mpfc_left = 44, mpfc_right = 6,
sma_left = 40, sma_right = 45)
stutter <- get_connectivity(d1, covariates = c("(1 | participant)"))
brain_viz(stutter, view = "top", jitter_val = .05)
``````{r, echo = FALSE, message = FALSE, warning = FALSE}
d1 <- import_nirs("~/Box/Stuttering Writing Group/PhoneCallsStutter/",
ldlpfc = 22, rdlpfc = c(39, 40), mpfc = c(44, 45), ifg = 6, ipl = 4)
stutter <- get_connectivity(d1, covariates = c("(1 | participant)"))
brain_viz(stutter, view = "left", jitter_val = .05)
``````{r, echo = FALSE, message = FALSE, warning = FALSE}
d1 <- import_nirs("~/Box/Stuttering Writing Group/PhoneCallsStutter/",
ldlpfc = 22, rdlpfc = c(39, 40), mpfc = c(44, 45), smg = 6, ang = 4)
stutter <- get_connectivity(d1, covariates = c("(1 | participant)"))
brain_viz(stutter, view = "right", jitter_val = .05)
```## Conclusion
This package is designed to import/clean, analyze, and visualize a specific set of data. If your data do not follow the general outline shown above, then this package will likely throw errors. It is still in heavy development. Contact for questions or comments.