diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..0ff7772 --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1,9 @@ +^neuromat\.Rproj$ +^\.Rproj\.user$ +^LICENSE\.md$ +^README\.Rmd$ +^\.github$ +^_pkgdown\.yml$ +^docs$ +^pkgdown$ +^man-roxygen$ diff --git a/.github/.gitignore b/.github/.gitignore new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/.github/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml new file mode 100644 index 0000000..74d8c97 --- /dev/null +++ b/.github/workflows/R-CMD-check.yaml @@ -0,0 +1,49 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +name: R-CMD-check + +jobs: + R-CMD-check: + runs-on: ${{ matrix.config.os }} + + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + + strategy: + fail-fast: false + matrix: + config: + - {os: macos-latest, r: 'release'} + - {os: windows-latest, r: 'release'} + - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} + - {os: ubuntu-latest, r: 'release'} + - {os: ubuntu-latest, r: 'oldrel-1'} + + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::rcmdcheck + needs: check + + - uses: r-lib/actions/check-r-package@v2 + with: + upload-snapshots: true diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml new file mode 100644 index 0000000..a7276e8 --- /dev/null +++ b/.github/workflows/pkgdown.yaml @@ -0,0 +1,48 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + release: + types: [published] + workflow_dispatch: + +name: pkgdown + +jobs: + pkgdown: + runs-on: ubuntu-latest + # Only restrict concurrency for non-PR jobs + concurrency: + group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages 🚀 + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.5.0 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a948606 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.Rproj.user +docs +inst/doc diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..d422220 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,30 @@ +Package: neuromat +Title: Create Model Matrices for Neuroimaging Analyses +Version: 0.0.0.9000 +Authors@R: + person( + given = "Athanasia Mo", + family = "Mowinckel", + email = "a.m.mowinckel@psykologi.uio.no", + role = c("aut", "cre"), + comment = c(ORCID = "0000-0002-5756-0223")) +Description: Neuroimaging software often requires the specification + of model matrices to run analyses. These can be difficult to + correctly. This package helps neuroscientists to create such + This includes creating qdec-files for Freesurfer Linear Mixes + Effects models. +License: MIT + file LICENSE +Encoding: UTF-8 +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.2.3 +Imports: + grDevices, + methods, + stats, + utils +URL: https://github.com/capro-uio/neuromat, http://www.capro.dev/neuromat/ +BugReports: https://github.com/capro-uio/neuromat/issues +Suggests: + knitr, + rmarkdown +VignetteBuilder: knitr diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5021435 --- /dev/null +++ b/LICENSE @@ -0,0 +1,2 @@ +YEAR: 2024 +COPYRIGHT HOLDER: freesurfer.lme authors diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..8ea9381 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright (c) 2024 freesurfer.lme authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..b8f7dc0 --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,11 @@ +# Generated by roxygen2: do not edit by hand + +S3method(plot,qdec) +export(make_fs_qdec) +export(qdec) +export(scale_vec) +importFrom(grDevices,hcl.colors) +importFrom(methods,is) +importFrom(stats,heatmap) +importFrom(stats,model.matrix) +importFrom(utils,write.csv) diff --git a/R/qdec.R b/R/qdec.R new file mode 100644 index 0000000..6e5ba5a --- /dev/null +++ b/R/qdec.R @@ -0,0 +1,163 @@ +#' Create a Freesurfer qdec +#' +#' Create a Freesurfer qdec from a model formula, +#' utilising R's robust model formula syntax. The function +#' also scales continuous variables, and can keep the original +#' data in the output. +#' +#' @details +#' The \code{\link{formula}} should in all likelihood also +#' include the \code{-1} to remove the intercept, as this +#' will provide a matrix where all levels of factor variables +#' have their own binary column. This is necessary to follow +#' the steps from the Freesurfer documentation. +#' +#' It is highly recommended to have the base-id's for Freesurfer +#' in their own column, and request to have this remain +#' in the qdec by using the id-column's name in the +#' \code{keep} argument. +#' +#' @param data data.frame, list or environment +#' containing the data. Neither matrix nor an array +#' will be accepted. +#' @template formula +#' @param path an option file path to write qdec to csv +#' @param keep logical or vector of column names, +#' to keep the original data in the output. +#' Default is \code{FALSE}. +#' +#' @return data.frame with model matrix and +#' scaled continuous variables. +#' @export +#' @importFrom stats model.matrix +#' @importFrom utils write.csv +#' @importFrom methods is +#' +#' @examples +#' cars <- mtcars +#' cars$cyl <- as.factor(cars$cyl) +#' cars$gear <- as.factor(cars$gear) +#' +#' make_fs_qdec(cars, mpg ~ cyl + hp) +#' +#' # Remove the intercept, necessary to follow +#' # steps from Freesurfer docs +#' make_fs_qdec(cars, mpg ~ -1 + cyl + hp) +#' make_fs_qdec(cars, mpg ~ -1 + cyl + hp + gear) +#' +#' # Keep the original data also in the output +#' make_fs_qdec(cars, mpg ~ -1 + cyl + hp, keep = TRUE) +#' +#' # Keep the original data of specific columns +#' # Use a character vector +#' make_fs_qdec(cars, mpg ~ -1 + cyl + hp, keep = c("mpg", "gear")) +#' +make_fs_qdec <- function(data, + formula, + path = NULL, + keep = FALSE) { + if(all( + is(keep, "character") & + keep == "" + )){ + stop("`keep` cannot be ''. Use TRUE/FALSE or the names of columns.", call. = FALSE) + } + + qdec <- qdec(data, formula) + vars <- attr(qdec, "vars") + + if(is(keep, "character")){ + vars <- keep + } + data <- data[ , vars, drop = FALSE] + + add_orig <- suppressWarnings( + any(keep, is.character(keep)) + ) + if(add_orig){ + qdec <- cbind(qdec, data) + } + + # write to path if requested + if(!is.null(path)){ + write.csv(qdec, path, row.names = FALSE) + } + + qdec +} + +#' Freesurfer qdec constructor +#' +#' Creates a qdec matrix from a model formula. +#' +#' @param data input data.frame +#' @template formula +#' +#' @return qdec with model matrix +#' @export +#' +#' @examples +#' cars <- mtcars +#' cars$cyl <- as.factor(cars$cyl) +#' +#' qdec <- qdec(cars, mpg ~ cyl + hp) +qdec <- function(data, formula){ + # extract variable names from formula + vars <- all.vars(formula) + + # create model matrix + mm <- model.matrix(formula, data) + mm <- as.data.frame(mm) + mm <- mm[, !names(mm) %in% names(data)] + + # scale continuous variables + dataz <- scale_num_data(data, vars) + + # combine model matrix and scaled data + qdec <- cbind(mm, dataz) + + structure( + qdec, + class = c("qdec", "tbl", "data.frame"), + formula = formula, + vars = vars + ) +} + + +#' Plot qdec matrix +#' +#' Visualise a Freesurfer qdec matrix as returned +#' byt the \code{\link{make_fs_qdec}} function. +#' +#' @param x a qdec object +#' @param col a vector of colors to be used in the heatmap. +#' @param ... arguments to be passed to \code{\link{heatmap}}. +#' \code{scale}, \code{Rowv}, \code{Colv} already have +#' custom values that may not be overwritten for the sake +#' of a better visualisation. +#' +#' @return a heatmap of the qdec matrix +#' @export +#' @importFrom grDevices hcl.colors +#' @importFrom stats heatmap +#' @examples +#' cars <- mtcars +#' cars$cyl <- as.factor(cars$cyl) +#' +#' qdec <- make_fs_qdec(cars, mpg ~ -1 + cyl + hp) +#' plot(qdec) +plot.qdec <- function(x, + col = hcl.colors(12, "viridis"), + ...) { + if(!inherits(x, "qdec")){ + stop("Input `x` must be a qdec object", call. = FALSE) + } + x <- x[, !names(x) %in% attr(x, "vars")] + x <- as.matrix(x) + x <- x[dim(x)[1]:1, ] + heatmap(x, scale = "none", + Rowv = NA, Colv = NA, + col = col, + ...) +} diff --git a/R/utils.R b/R/utils.R new file mode 100644 index 0000000..971fbea --- /dev/null +++ b/R/utils.R @@ -0,0 +1,27 @@ +#' Scale a numeric vector +#' +#' @param x numeric vector to scale +#' @param ... additional arguments to be passed to \code{\link{scale}} +#' +#' @return scaled vector +#' @export +#' @keywords internal +#' @examples +#' scale_vec(1:20) +scale_vec <- function(x, ...) { + # Error if x has more than one dimension + if(!is.null(dim(x))){ + stop("Input `x` must be a vector", call. = FALSE) + } + as.numeric(scale(x, ...)) +} + +scale_num_data <- function(data, formula){ + # scale continuous variables + cl <- sapply(data, class) + dataz <- data[,which(cl %in% "numeric")] + dataz <- apply(dataz, 2, scale_vec) + dataz <- as.data.frame(dataz, check.names = FALSE) + names(dataz) <- paste0(names(dataz), "z") + dataz +} diff --git a/README.Rmd b/README.Rmd new file mode 100644 index 0000000..29c0c0c --- /dev/null +++ b/README.Rmd @@ -0,0 +1,53 @@ +--- +output: github_document +--- + + + +```{r, include = FALSE} +options(max.print = 60) +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + fig.path = "man/figures/README-", + out.width = "100%" +) +``` + +# neuromat + + +[![R-CMD-check](https://github.com/capro-uio/neuromat/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/capro-uio/neuromat/actions/workflows/R-CMD-check.yaml) +[![CRAN status](https://www.r-pkg.org/badges/version/neuromat)](https://CRAN.R-project.org/package=neuromat) +[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) + + +Running vertex-wise linear mixed effects models in [Freesurfer](https://surfer.nmr.mgh.harvard.edu/fswiki/LinearMixedEffectsModels) requires a specific file format. +The qdec format requires neatly created binary columns for +categorical value levels, and is made more efficient if continuous +variables are scaled (or de-meaned). +This package provides functions to create these files from R. + + +## Installation + +You can install the development version of `neuromat` like so: + +``` r +# Install Capro R-universe +install.packages('neuromat', + repos = 'https://capro-uio.r-universe.dev') +``` + +## Example + +```{r} +library(neuromat) +cars <- mtcars +cars$cyl <- factor(cars$cyl) +cars$gear <- factor(cars$gear) +qdec <- make_fs_qdec(cars, mpg ~ -1 + cyl + hp) +qdec + +plot(qdec) +``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..eb4538b --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ + + + +# neuromat + + + +[![R-CMD-check](https://github.com/capro-uio/neuromat/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/capro-uio/neuromat/actions/workflows/R-CMD-check.yaml) +[![CRAN +status](https://www.r-pkg.org/badges/version/neuromat)](https://CRAN.R-project.org/package=neuromat) +[![Lifecycle: +experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) + + +Running vertex-wise linear mixed effects models in +[Freesurfer](https://surfer.nmr.mgh.harvard.edu/fswiki/LinearMixedEffectsModels) +requires a specific file format. The qdec format requires neatly created +binary columns for categorical value levels, and is made more efficient +if continuous variables are scaled (or de-meaned). This package provides +functions to create these files from R. + +## Installation + +You can install the development version of `neuromat` like so: + +``` r +# Install Capro R-universe +install.packages('neuromat', + repos = 'https://capro-uio.r-universe.dev') +``` + +## Example + +Add child document from vignette + +``` r +library(neuromat) +cars <- mtcars +cars$cyl <- factor(cars$cyl) +cars$gear <- factor(cars$gear) +qdec <- make_fs_qdec(cars, mpg ~ -1 + cyl + hp) +qdec +#> cyl4 cyl6 cyl8 mpgz hpz +#> Mazda RX4 0 1 0 0.1508848 -0.5350928 +#> Mazda RX4 Wag 0 1 0 0.1508848 -0.5350928 +#> Datsun 710 1 0 0 0.4495434 -0.7830405 +#> Hornet 4 Drive 0 1 0 0.2172534 -0.5350928 +#> Hornet Sportabout 0 0 1 -0.2307345 0.4129422 +#> Valiant 0 1 0 -0.3302874 -0.6080186 +#> Duster 360 0 0 1 -0.9607889 1.4339030 +#> Merc 240D 1 0 0 0.7150178 -1.2351802 +#> Merc 230 1 0 0 0.4495434 -0.7538702 +#> Merc 280 0 1 0 -0.1477738 -0.3454858 +#> Merc 280C 0 1 0 -0.3800638 -0.3454858 +#> Merc 450SE 0 0 1 -0.6123539 0.4858679 +#> [ reached 'max' / getOption("max.print") -- omitted 20 rows ] + +plot(qdec) +``` + + diff --git a/_pkgdown.yml b/_pkgdown.yml new file mode 100644 index 0000000..67161e7 --- /dev/null +++ b/_pkgdown.yml @@ -0,0 +1,4 @@ +url: http://www.capro.dev/freesurfer.lme/ +template: + bootstrap: 5 + diff --git a/man-roxygen/formula.R b/man-roxygen/formula.R new file mode 100644 index 0000000..dcb0126 --- /dev/null +++ b/man-roxygen/formula.R @@ -0,0 +1,5 @@ +#' @param formula a model \code{\link{formula}} or +#' \code{\link{terms}} object. For simple qdec file, +#' with binary columns for all levels of a factor, +#' make sure to include a formula with \code{-1} to +#' remove the intercept. diff --git a/man/figures/README-example4-1.png b/man/figures/README-example4-1.png new file mode 100644 index 0000000..6830190 Binary files /dev/null and b/man/figures/README-example4-1.png differ diff --git a/man/figures/README-unnamed-chunk-2-1.png b/man/figures/README-unnamed-chunk-2-1.png new file mode 100644 index 0000000..e6f4ff4 Binary files /dev/null and b/man/figures/README-unnamed-chunk-2-1.png differ diff --git a/man/make_fs_qdec.Rd b/man/make_fs_qdec.Rd new file mode 100644 index 0000000..1ca109e --- /dev/null +++ b/man/make_fs_qdec.Rd @@ -0,0 +1,67 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/qdec.R +\name{make_fs_qdec} +\alias{make_fs_qdec} +\title{Create a Freesurfer qdec} +\usage{ +make_fs_qdec(data, formula, path = NULL, keep = FALSE) +} +\arguments{ +\item{data}{data.frame, list or environment +containing the data. Neither matrix nor an array +will be accepted.} + +\item{formula}{a model \code{\link{formula}} or +\code{\link{terms}} object. For simple qdec file, +with binary columns for all levels of a factor, +make sure to include a formula with \code{-1} to +remove the intercept.} + +\item{path}{an option file path to write qdec to csv} + +\item{keep}{logical or vector of column names, +to keep the original data in the output. +Default is \code{FALSE}.} +} +\value{ +data.frame with model matrix and +scaled continuous variables. +} +\description{ +Create a Freesurfer qdec from a model formula, +utilising R's robust model formula syntax. The function +also scales continuous variables, and can keep the original +data in the output. +} +\details{ +The \code{\link{formula}} should in all likelihood also +include the \code{-1} to remove the intercept, as this +will provide a matrix where all levels of factor variables +have their own binary column. This is necessary to follow +the steps from the Freesurfer documentation. + +It is highly recommended to have the base-id's for Freesurfer +in their own column, and request to have this remain +in the qdec by using the id-column's name in the +\code{keep} argument. +} +\examples{ +cars <- mtcars +cars$cyl <- as.factor(cars$cyl) +cars$gear <- as.factor(cars$gear) + +make_fs_qdec(cars, mpg ~ cyl + hp) + +# Remove the intercept, necessary to follow +# steps from Freesurfer docs +make_fs_qdec(cars, mpg ~ -1 + cyl + hp) +make_fs_qdec(cars, mpg ~ -1 + cyl + hp + gear) + +# Keep the original data also in the output +make_fs_qdec(cars, mpg ~ -1 + cyl + hp, keep = TRUE) + +# Keep the original data of specific columns +# Use a character vector +make_fs_qdec(cars, mpg ~ -1 + cyl + hp, keep = c("mpg", "gear")) + +} diff --git a/man/plot.qdec.Rd b/man/plot.qdec.Rd new file mode 100644 index 0000000..881230d --- /dev/null +++ b/man/plot.qdec.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/qdec.R +\name{plot.qdec} +\alias{plot.qdec} +\title{Plot qdec matrix} +\usage{ +\method{plot}{qdec}(x, col = hcl.colors(12, "viridis"), ...) +} +\arguments{ +\item{x}{a qdec object} + +\item{col}{a vector of colors to be used in the heatmap.} + +\item{...}{arguments to be passed to \code{\link{heatmap}}. +\code{scale}, \code{Rowv}, \code{Colv} already have +custom values that may not be overwritten for the sake +of a better visualisation.} +} +\value{ +a heatmap of the qdec matrix +} +\description{ +Visualise a Freesurfer qdec matrix as returned +byt the \code{\link{make_fs_qdec}} function. +} +\examples{ +cars <- mtcars +cars$cyl <- as.factor(cars$cyl) + +qdec <- make_fs_qdec(cars, mpg ~ -1 + cyl + hp) +plot(qdec) +} diff --git a/man/qdec.Rd b/man/qdec.Rd new file mode 100644 index 0000000..0ea43af --- /dev/null +++ b/man/qdec.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/qdec.R +\name{qdec} +\alias{qdec} +\title{Freesurfer qdec constructor} +\usage{ +qdec(data, formula) +} +\arguments{ +\item{data}{input data.frame} + +\item{formula}{a model \code{\link{formula}} or +\code{\link{terms}} object. For simple qdec file, +with binary columns for all levels of a factor, +make sure to include a formula with \code{-1} to +remove the intercept.} +} +\value{ +qdec with model matrix +} +\description{ +Creates a qdec matrix from a model formula. +} +\examples{ +cars <- mtcars +cars$cyl <- as.factor(cars$cyl) + +qdec <- qdec(cars, mpg ~ cyl + hp) +} diff --git a/man/scale_vec.Rd b/man/scale_vec.Rd new file mode 100644 index 0000000..4daae8d --- /dev/null +++ b/man/scale_vec.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{scale_vec} +\alias{scale_vec} +\title{Scale a numeric vector} +\usage{ +scale_vec(x, ...) +} +\arguments{ +\item{x}{numeric vector to scale} + +\item{...}{additional arguments to be passed to \code{\link{scale}}} +} +\value{ +scaled vector +} +\description{ +Scale a numeric vector +} +\examples{ +scale_vec(1:20) +} +\keyword{internal} diff --git a/neuromat.Rproj b/neuromat.Rproj new file mode 100644 index 0000000..69fafd4 --- /dev/null +++ b/neuromat.Rproj @@ -0,0 +1,22 @@ +Version: 1.0 + +RestoreWorkspace: No +SaveWorkspace: No +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +AutoAppendNewline: Yes +StripTrailingWhitespace: Yes +LineEndingConversion: Posix + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace diff --git a/vignettes/.gitignore b/vignettes/.gitignore new file mode 100644 index 0000000..097b241 --- /dev/null +++ b/vignettes/.gitignore @@ -0,0 +1,2 @@ +*.html +*.R diff --git a/vignettes/neuromat.Rmd b/vignettes/neuromat.Rmd new file mode 100644 index 0000000..3567634 --- /dev/null +++ b/vignettes/neuromat.Rmd @@ -0,0 +1,116 @@ +--- +title: "Getting started with Neuromat" +output: rmarkdown::html_vignette +vignette: | + %\VignetteIndexEntry{Getting started with Neuromat} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +options(max.print = 100) +knitr::opts_chunk$set( +collapse = TRUE, +comment = "#>" +) +``` + +Leveraging R's power of making models, we can create a QDEC file from a model formula and a data frame. +The function relies on the correct setup of data (categoricals as factors etc), which you would normally do in R. + +```{r setup} +library(neuromat) +``` + + +First, we prepare a data.frame. +We will use the `mtcars` data to imagine what we want to do. +We will make sure to convert the `cyl` and `gear` columns to factors, to prepare ourselves for how to deal with categorical +variables in the qdec file. + +```{r dataprep} +cars <- mtcars +cars$cyl <- factor(cars$cyl) +cars$gear <- factor(cars$gear) +cars +``` + + +### The model formula + +To create a qdec object, we use the `make_fs_qdec` function, +with a formula and the data. +The formula decides what variables the qdec file will contain, +and will binarise the levels of factors, +and scale continuous variables so they have a mean of 0 and +a standard deviation of 1. +Make sure to include `-1` to remove intercept, +which would make sure that factors have all levels represented in the qdec file. + +```{r example1} +make_fs_qdec(cars, mpg ~ -1 + cyl + hp) +``` + +If you do not include `-1`, the model will not expose all levels of factors, +but capture the first levels of each factor in the `Intercept` +which will consist of only the value `1`. + +```{r example2} +make_fs_qdec(cars, mpg ~ cyl + hp) +``` + + +`-1` makes sure you get a qdec as expected +from the [Freesurfer documentation](https://surfer.nmr.mgh.harvard.edu/fswiki/LinearMixedEffectsModels) + +### Keeping original data + +You can keep the original data in the qdec file by using the `keep` argument. +This is useful if you want to keep the original data for reference, +or if you want to use the qdec file for other purposes than just running a model. +By default, `keep` is `FALSE`, and by switching to `TRUE` you keep the original data _of the columns in your model_. + + +```{r keep1} +make_fs_qdec(cars, mpg ~ -1 + cyl + hp, keep = TRUE) +``` + +It is recommended that you also have the base-id's of the data in their own column, which you can also request to have +in the qdec by using the id-column's name in the `keep` argument. + +```{r keep2} +cars$type <- row.names(cars) +make_fs_qdec(cars, + mpg ~ -1 + cyl + hp + gear, + keep = "type") +``` + +This can also be a character vector, and let's you specify which columns to keep. + +```{r keep3} +cars$type <- row.names(cars) +make_fs_qdec( + cars, + mpg ~ -1 + cyl + hp + gear, + keep = c("type", "mpg", "cyl", "hp") +) + +# Keeping all columns +make_fs_qdec( + cars, + mpg ~ -1 + cyl + hp, + keep = names(cars)) +``` + + + +### Plotting the qdec + +Visualise the qdec file with the `plot` function. +This is a good way to confirm what you expect the data to look like. + +```{r example4} +qdec <- make_fs_qdec(cars, + mpg ~ -1 + cyl + hp + gear) +plot(qdec) +```