diff --git a/DESCRIPTION b/DESCRIPTION index 34aeacf..ec31a17 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: mxmmod Type: Package Title: Measurement Model of Derivatives (MMOD) in OpenMx -Version: 0.1.0 +Version: 1.0.0 Authors@R: c( person( given = 'Kyle', @@ -16,8 +16,8 @@ Authors@R: c( ) ) Description: This package provides a convenient interface for building - Measurement Model of Derivatives (MMOD; Estabrook, 2015) in OpenMx -License: Apache 2.0 + Measurement Model of Derivatives (MMOD; Estabrook, 2015) in OpenMx. +License: file LICENSE Encoding: UTF-8 LazyData: true Imports: @@ -25,6 +25,8 @@ Imports: Suggests: knitr, rmarkdown, - testthat + testthat, + tidyverse VignetteBuilder: knitr RoxygenNote: 6.1.1 +Depends: R (>= 2.10) diff --git a/NAMESPACE b/NAMESPACE index d75f824..9159e7c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1 +1,3 @@ -exportPattern("^[[:alpha:]]+") +# Generated by roxygen2: do not edit by hand + +export(mxMmodModel) diff --git a/R/data.R b/R/data.R new file mode 100644 index 0000000..ca12097 --- /dev/null +++ b/R/data.R @@ -0,0 +1,19 @@ +#' NLSY97 Longitudinal Depression Scale Data +#' +#' A 5-item depression scale used on the National Longitudinal +#' Survey of Youth, 1997 sample (NLSY97). Individuals were assessed +#' in 2000, 2002, and 2004. All items are assessed on a 4-point +#' likert scale. +#' +#' @format A data frame with 26952 rows and 7 variables: +#' \describe{ +#' \item{pid}{Unique ID of participant} +#' \item{occasion}{Measurement occasion} +#' \item{nervous}{How often participant felt 'like a nervous person'} +#' \item{calm}{How often participant felt 'calm and peaceful'} +#' \item{down}{How often participant felt 'down or blue'} +#' \item{happy}{How often participant felt 'like a happy person'} +#' \item{depressed}{How often participant felt 'depressed'} +#' } +#' @source \url{https://www.bls.gov/nls/nlsy97.htm} +"nlsy97depression" diff --git a/R/mxMmodModel.R b/R/mxMmodModel.R index 7bf68ad..2843cee 100644 --- a/R/mxMmodModel.R +++ b/R/mxMmodModel.R @@ -24,7 +24,7 @@ #' \code{list(F1 = c('m1', 'm2', 'm3'), F2 = c('m4', 'm5', 'm6'))} #' #' @examples -#' data("nlsy97depression") +#' data(nlsy97depression) #' # Fit one factor MMOD #' structure <- list( #' F1 = c('nervous', 'down', 'depressed', 'calm', 'happy') @@ -32,8 +32,9 @@ #' mmod_model <- mxMmodModel(data=nlsy97depression, #' modelName='1 Factor MMOD', #' idvar='pid', timevar='occasion', structure=structure) -#' mmod_fit <- mxRun(mmod_model) +#' mmod_fit <- OpenMx::mxRun(mmod_model) #' summary(mmod_fit) +#' @export mxMmodModel <- function(data, modelName, idvar, timevar, structure, fiml=F) { derivName <- function(o, m) {paste0('d', m, '_', o)} # derivName(1, 'nervous') -> dnervous_1 @@ -107,53 +108,60 @@ mxMmodModel <- function(data, modelName, idvar, timevar, structure, fiml=F) { manifests <- unique(unlist(derivStruct)) data <- data[c(idvar, timevar, unlist(structure))] - data <- reshape(as.data.frame(data), timevar=timevar, idvar=idvar, direction='wide', sep='_')[-1] + data <- stats::reshape(as.data.frame(data), timevar=timevar, idvar=idvar, direction='wide', sep='_')[-1] stopifnot(setequal(manifests, names(data))) # Sanity check # OpenMx manifest ordering bug: https://github.com/OpenMx/OpenMx/issues/247 data <- data[manifests] if (fiml) { - mxd <- mxData(data, type="raw") + mxd <- OpenMx::mxData(data, type="raw") } else { if (any(is.na(data))) { warning('Missing values detected; omitting them.') } - df_subset <- na.omit(data) - df_cov <- cov(df_subset) - mxd <- mxData(df_cov, type="cov", numObs=nrow(df_subset)) + df_subset <- stats::na.omit(data) + df_cov <- stats::cov(df_subset) + mxd <- OpenMx::mxData(df_cov, type="cov", numObs=nrow(df_subset)) } # Make weight matrix with Deboeck’s functions weight <- ContrastsGOLD(occasions_num, length(occasions_num) - 1) weightList <- as.list(as.data.frame(t(weight))) - do.call('mxModel', c(list( + do.call(OpenMx::mxModel, c(list( modelName, mxd, type="RAM", manifestVars=manifests, latentVars=c(factors, derivatives), # factor loadings mapply(function(fct, drv) { - mxPath(from=fct, to=drv, values=0.5, free=T) + OpenMx::mxPath(from=fct, to=drv, values=0.5, free=T) }, names(factorStruct), factorStruct), # factor variances - mxPath(from=factors, arrows=2, values=1, free=F), + OpenMx::mxPath(from=factors, arrows=2, values=1, free=F), # factor correlations - mxPath(from=factors, arrows=2, connect="unique.bivariate", free=T), + OpenMx::mxPath(from=factors, arrows=2, connect="unique.bivariate", free=T), # residual variances(only for latent derivatives !) - mxPath(from=derivatives, arrows=2, values=1)), + OpenMx::mxPath(from=derivatives, arrows=2, values=1)), # transformation mapply(function(dgrp, weight) { mapply(function(drv, mnf) { - mxPath(from=drv, to=mnf, free=F, values=weight) + OpenMx::mxPath(from=drv, to=mnf, free=F, values=weight) }, names(dgrp), dgrp) }, derivStruct, weightList), # saturate model - if (fiml) mxPath(from = 'one', to = manifests) else list() + if (fiml) OpenMx::mxPath(from = 'one', to = manifests) else list() )) } -# Code from Deboeck (2010) +#' Generate GOLD contrasts +#' +#' Code from Deboeck (2010) +#' +#' @param T timeseries +#' @param max max derivatives +#' +#' @keywords internal ContrastsGOLD <- function(T, max) { Xi <- matrix(NA, length(T), length(T)) for(r in 0:(length(T)-1)) { diff --git a/data-raw/nlsy97depression.R b/data-raw/nlsy97depression.R index fdd1857..1323137 100644 --- a/data-raw/nlsy97depression.R +++ b/data-raw/nlsy97depression.R @@ -1,4 +1,7 @@ +# Create nlsy97 depression data set +# # Public domain data from nlsy97: https://www.bls.gov/nls/nlsy97.htm +# var_list <- list( pid = 'R0000100', diff --git a/man/ContrastsGOLD.Rd b/man/ContrastsGOLD.Rd new file mode 100644 index 0000000..0b36e5f --- /dev/null +++ b/man/ContrastsGOLD.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/mxMmodModel.R +\name{ContrastsGOLD} +\alias{ContrastsGOLD} +\title{Generate GOLD contrasts} +\usage{ +ContrastsGOLD(T, max) +} +\arguments{ +\item{T}{timeseries} + +\item{max}{max derivatives} +} +\description{ +Code from Deboeck (2010) +} +\keyword{internal} diff --git a/man/mxMmodModel.Rd b/man/mxMmodModel.Rd index b5c7fea..3993fb3 100644 --- a/man/mxMmodModel.Rd +++ b/man/mxMmodModel.Rd @@ -38,7 +38,7 @@ And a two factor structure would be: \code{list(F1 = c('m1', 'm2', 'm3'), F2 = c('m4', 'm5', 'm6'))} } \examples{ -data("nlsy97depression") +data(nlsy97depression) # Fit one factor MMOD structure <- list( F1 = c('nervous', 'down', 'depressed', 'calm', 'happy') @@ -46,6 +46,6 @@ structure <- list( mmod_model <- mxMmodModel(data=nlsy97depression, modelName='1 Factor MMOD', idvar='pid', timevar='occasion', structure=structure) -mmod_fit <- mxRun(mmod_model) +mmod_fit <- OpenMx::mxRun(mmod_model) summary(mmod_fit) } diff --git a/man/nlsy97depression.Rd b/man/nlsy97depression.Rd new file mode 100644 index 0000000..87c9cc9 --- /dev/null +++ b/man/nlsy97depression.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{nlsy97depression} +\alias{nlsy97depression} +\title{NLSY97 Longitudinal Depression Scale Data} +\format{A data frame with 26952 rows and 7 variables: +\describe{ + \item{pid}{Unique ID of participant} + \item{occasion}{Measurement occasion} + \item{nervous}{How often participant felt 'like a nervous person'} + \item{calm}{How often participant felt 'calm and peaceful'} + \item{down}{How often participant felt 'down or blue'} + \item{happy}{How often participant felt 'like a happy person'} + \item{depressed}{How often participant felt 'depressed'} +}} +\source{ +\url{https://www.bls.gov/nls/nlsy97.htm} +} +\usage{ +nlsy97depression +} +\description{ +A 5-item depression scale used on the National Longitudinal +Survey of Youth, 1997 sample (NLSY97). Individuals were assessed +in 2000, 2002, and 2004. All items are assessed on a 4-point +likert scale. +} +\keyword{datasets} diff --git a/tests/testthat/test-refimpl.R b/tests/testthat/test-refimpl.R index 17128db..1d5eb8d 100644 --- a/tests/testthat/test-refimpl.R +++ b/tests/testthat/test-refimpl.R @@ -1,6 +1,7 @@ context('Reference implementation comparison') mxmmod_ref <- function(df, do_fiml=F) { + require(OpenMx) require(mxmmod) structure <- list( F1 = c('nervous', 'down', 'depressed', 'calm', 'happy') diff --git a/vignettes/mmod_tutorial.Rmd b/vignettes/mmod_tutorial.Rmd index 7c98d75..a1f0f4d 100644 --- a/vignettes/mmod_tutorial.Rmd +++ b/vignettes/mmod_tutorial.Rmd @@ -7,6 +7,7 @@ vignette: > %\VignetteIndexEntry{Getting Started with mxmmod} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} + %\VignetteDepends{tidyverse} --- ```{r setup, include = FALSE} @@ -35,13 +36,7 @@ E. Discussion ### Prelim: Prepare environment -Before we begin, install the `mxmmod` package if you have not already: - -```{r, eval=F} -devtools::install_github('khusmann/mxmmod') -``` - -Now let's load the required libraries for this tutorial: +First, let's load the required libraries for this tutorial: ```{r, message=F, warning=F} library(tidyverse)