├── .Rbuildignore ├── .github ├── .gitignore ├── CONTRIBUTING.md └── workflows │ ├── R-CMD-check.yaml │ ├── lint.yaml │ ├── pkgdown.yaml │ ├── rhub.yaml │ └── test-coverage.yaml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── DESCRIPTION ├── LICENSE.md ├── NAMESPACE ├── R ├── RcppExports.R ├── VarCorr.R ├── anova.galamm.R ├── coef.R ├── confint.R ├── data.R ├── define_factor_mappings.R ├── extract_optim_parameters.R ├── factor_loadings.R ├── family.R ├── fitted.galamm.R ├── fixef.R ├── formula.R ├── galamm-package.R ├── galamm.R ├── galamm_control.R ├── gamm4-functions.R ├── logLik.galamm.R ├── mgcv-functions.R ├── misc.R ├── plot.galamm.R ├── plot_smooth.R ├── predict.galamm.R ├── ranef.R ├── residuals.galamm.R ├── response.R ├── sigma.R ├── smooths.R ├── srr-stats-standards.R ├── summary.galamm.R └── vcov.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── codecov.yml ├── codemeta.json ├── cran-comments.md ├── data-raw ├── cognition.R ├── diet.R ├── diet.dat ├── epilep.R ├── hsced.R ├── latent_covariates.R ├── lifespan.R ├── mresp.R └── trajectories.rds ├── data ├── cognition.rda ├── diet.rda ├── epilep.rda ├── hsced.rda ├── latent_covariates.rda ├── latent_covariates_long.rda ├── lifespan.rda ├── mresp.rda └── mresp_hsced.rda ├── dev-scripts ├── create-logo.R ├── gamm_factor_structure.R ├── latent-interactions.R ├── lifespan_demo.R ├── logo-raw.jpg ├── multiple_loadings.R ├── predict-mixed-response.R ├── predict-newdata.R ├── predict-semiparametric.R ├── sanitize.R └── testdata-multiple-factors.R ├── galamm.Rproj ├── insert_sparse_autodiff.R ├── inst ├── CITATION ├── REFERENCES.bib ├── figures │ └── galamm.png ├── include │ └── autodiff │ │ ├── common │ │ ├── binomialcoefficient.hpp │ │ ├── classtraits.hpp │ │ ├── eigen.hpp │ │ ├── meta.hpp │ │ ├── numbertraits.hpp │ │ └── vectortraits.hpp │ │ ├── forward │ │ ├── dual.hpp │ │ ├── dual │ │ │ ├── dual.hpp │ │ │ └── eigen.hpp │ │ ├── real.hpp │ │ ├── real │ │ │ ├── eigen.hpp │ │ │ └── real.hpp │ │ └── utils │ │ │ ├── derivative.hpp │ │ │ ├── gradient.hpp │ │ │ └── taylorseries.hpp │ │ └── reverse │ │ ├── var.hpp │ │ └── var │ │ ├── eigen.hpp │ │ └── var.hpp └── testdata │ └── test_multiple_factors.rds ├── man ├── VarCorr.Rd ├── anova.galamm.Rd ├── coef.galamm.Rd ├── cognition.Rd ├── confint.galamm.Rd ├── deviance.galamm.Rd ├── diet.Rd ├── epilep.Rd ├── extract_optim_parameters.galamm.Rd ├── factor_loadings.galamm.Rd ├── family.galamm.Rd ├── figures │ ├── README-pressure-1.png │ ├── README-unnamed-chunk-10-1.png │ ├── README-unnamed-chunk-9-1.png │ └── logo.png ├── fitted.galamm.Rd ├── fixef.Rd ├── formula.galamm.Rd ├── galamm-package.Rd ├── galamm.Rd ├── galamm_control.Rd ├── hsced.Rd ├── latent_covariates.Rd ├── latent_covariates_long.Rd ├── lifespan.Rd ├── llikAIC.Rd ├── logLik.galamm.Rd ├── mresp.Rd ├── mresp_hsced.Rd ├── nobs.galamm.Rd ├── plot.galamm.Rd ├── plot_smooth.galamm.Rd ├── predict.galamm.Rd ├── print.VarCorr.galamm.Rd ├── print.galamm.Rd ├── print.summary.galamm.Rd ├── ranef.galamm.Rd ├── residuals.galamm.Rd ├── response.Rd ├── sigma.galamm.Rd ├── sl.Rd ├── summary.galamm.Rd ├── t2l.Rd └── vcov.galamm.Rd ├── news.md ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── rebuild-long-running-vignettes.R ├── src ├── .gitignore ├── Makevars ├── Makevars.win ├── RcppExports.cpp ├── compute_galamm.cpp ├── data.h ├── misc.h ├── model.h ├── parameters.h └── update_funs.h ├── tests ├── testthat.R └── testthat │ ├── _snaps │ ├── galamm-glmm.md │ ├── galamm-heteroscedastic.md │ ├── galamm-latent-covariates-interaction.md │ ├── galamm-lmm.md │ ├── galamm-mixed-resp.md │ ├── galamm-semiparametric.md │ └── galamm-setup.md │ ├── test-galamm-glmm.R │ ├── test-galamm-heteroscedastic.R │ ├── test-galamm-latent-covariates-interaction.R │ ├── test-galamm-lmm.R │ ├── test-galamm-mixed-resp.R │ ├── test-galamm-semiparametric.R │ ├── test-galamm-setup.R │ ├── test-misc.R │ └── test-parameter-recovery.R ├── update_autodiff.sh ├── vignettes-raw ├── glmm_factor.Rmd ├── latent_observed_interaction.Rmd ├── lmm_factor.Rmd ├── lmm_heteroscedastic.Rmd ├── mixed_response.Rmd ├── optimization.Rmd ├── scaling.Rmd └── semiparametric.Rmd └── vignettes ├── .gitignore ├── galamm.Rmd ├── glmm_factor.Rmd ├── glmm_factor_binomial_diagnostic-1.png ├── glmm_factor_poisson_diagnostic-1.png ├── glmm_factor_poisson_diagnostic_lme4-1.png ├── latent-observed-smooth-1.png ├── latent_observed_interaction.Rmd ├── lmm_factor.Rmd ├── lmm_factor_diagnostic_plot-1.png ├── lmm_heteroscedastic.Rmd ├── lmm_heteroscedastic_diagnostic-1.png ├── mixed_response.Rmd ├── optimization.Rmd ├── scaling-glmm-plot-1.png ├── scaling-hsced-plot-1.png ├── scaling-lmm-plot-1.png ├── scaling-semiparametric-binomial-plot-1.png ├── scaling-semiparametric-gaussian-plot-1.png ├── scaling.Rmd ├── semiparametric-gamm-binomial-1.png ├── semiparametric-gamm4-binomial-1.png ├── semiparametric-gaussian-by-factor1-1.png ├── semiparametric-gaussian-by-factor2-1.png ├── semiparametric-gaussian-factor-1.png ├── semiparametric-gaussian-gamm-diagnostic-1.png ├── semiparametric-gaussian-gamm-smooth1-1.png ├── semiparametric-gaussian-gamm-smooth2-1.png ├── semiparametric-gaussian-gamm-smooth2-2.png ├── semiparametric-gaussian-gamm4-diagnostic-1.png ├── semiparametric-gaussian-gamm4-smooth-1.png ├── semiparametric-mixed-by-factor1-1.png ├── semiparametric-mixed-by-factor2-1.png ├── semiparametric-mixedresponse-smooths1-1.png ├── semiparametric-mixedresponse-smooths2-1.png ├── semiparametric-mixedresponse-smooths3-1.png ├── semiparametric-multivariate-gaussian-smooth1-1.png ├── semiparametric-multivariate-gaussian-smooth2-1.png ├── semiparametric-multivariate-spaghetti-1.png ├── semiparametric-spaghetti-plot-1.png └── semiparametric.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^galamm\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README\.Rmd$ 4 | ^LICENSE\.md$ 5 | ^data-raw$ 6 | ^vignettes-raw$ 7 | 8 | ^\.github$ 9 | ^codecov\.yml$ 10 | ^dev-scripts$ 11 | ^_pkgdown\.yml$ 12 | ^docs$ 13 | ^pkgdown$ 14 | ^cran-comments\.md$ 15 | ^news\.md$ 16 | ^codemeta\.json$ 17 | ^CODE_OF_CONDUCT\.md$ 18 | ^CODE_OF_CONDUCT\.html$ 19 | 20 | rebuild-long-running-vignettes.R 21 | update_autodiff.sh 22 | insert_sparse_autodiff.R 23 | docker-sanitize.sh 24 | 25 | ^CRAN-SUBMISSION$ 26 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to galamm 2 | 3 | This outlines how to propose a change to galamm. 4 | For a detailed discussion on contributing to this and other tidyverse packages, please see the [development contributing guide](https://rstd.io/tidy-contrib) and our [code review principles](https://code-review.tidyverse.org/). 5 | 6 | ## Fixing typos 7 | 8 | You can fix typos, spelling mistakes, or grammatical errors in the documentation directly using the GitHub web interface, as long as the changes are made in the _source_ file. 9 | This generally means you'll need to edit [roxygen2 comments](https://roxygen2.r-lib.org/articles/roxygen2.html) in an `.R`, not a `.Rd` file. 10 | You can find the `.R` file that generates the `.Rd` by reading the comment in the first line. 11 | 12 | ## Bigger changes 13 | 14 | If you want to make a bigger change, it's a good idea to first file an issue and make sure someone from the team agrees that it’s needed. 15 | If you’ve found a bug, please file an issue that illustrates the bug with a minimal 16 | [reprex](https://www.tidyverse.org/help/#reprex) (this will also help you write a unit test, if needed). 17 | See our guide on [how to create a great issue](https://code-review.tidyverse.org/issues/) for more advice. 18 | 19 | ### Pull request process 20 | 21 | * Fork the package and clone onto your computer. If you haven't done this before, we recommend using `usethis::create_from_github("LCBC-UiO/galamm", fork = TRUE)`. 22 | 23 | * Install all development dependencies with `devtools::install_dev_deps()`, and then make sure the package passes R CMD check by running `devtools::check()`. 24 | If R CMD check doesn't pass cleanly, it's a good idea to ask for help before continuing. 25 | * Create a Git branch for your pull request (PR). We recommend using `usethis::pr_init("brief-description-of-change")`. 26 | 27 | * Make your changes, commit to git, and then create a PR by running `usethis::pr_push()`, and following the prompts in your browser. 28 | The title of your PR should briefly describe the change. 29 | The body of your PR should contain `Fixes #issue-number`. 30 | 31 | * For user-facing changes, add a bullet to the top of `NEWS.md` (i.e. just below the first header). Follow the style described in . 32 | 33 | ### Code style 34 | 35 | * New code should follow the tidyverse [style guide](https://style.tidyverse.org). 36 | You can use the [styler](https://CRAN.R-project.org/package=styler) package to apply these styles, but please don't restyle code that has nothing to do with your PR. 37 | 38 | * We use [roxygen2](https://cran.r-project.org/package=roxygen2), with [Markdown syntax](https://cran.r-project.org/web/packages/roxygen2/vignettes/rd-formatting.html), for documentation. 39 | 40 | * We use [testthat](https://cran.r-project.org/package=testthat) for unit tests. 41 | Contributions with test cases included are easier to accept. 42 | 43 | ## Code of Conduct 44 | 45 | Please note that the galamm project is released with a 46 | [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By contributing to this 47 | project you agree to abide by its terms. 48 | 49 | ## Roadmap 50 | 51 | This package is in a stable state of development, with some degree of active subsequent development as envisioned by the primary authors. 52 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | name: R-CMD-check 10 | 11 | jobs: 12 | R-CMD-check: 13 | runs-on: ${{ matrix.config.os }} 14 | 15 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | config: 21 | - {os: macos-latest, r: 'release'} 22 | - {os: windows-latest, r: 'release'} 23 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 24 | - {os: ubuntu-latest, r: 'release'} 25 | 26 | env: 27 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 28 | R_KEEP_PKG_SOURCE: yes 29 | GALAMM_EXTENDED_TESTS: ${{contains(github.event.head_commit.message, 30 | 'run-extended')}} 31 | 32 | steps: 33 | - uses: actions/checkout@v3 34 | 35 | - uses: r-lib/actions/setup-pandoc@v2 36 | 37 | - uses: r-lib/actions/setup-r@v2 38 | with: 39 | r-version: ${{ matrix.config.r }} 40 | http-user-agent: ${{ matrix.config.http-user-agent }} 41 | use-public-rspm: true 42 | 43 | - uses: r-lib/actions/setup-r-dependencies@v2 44 | with: 45 | extra-packages: any::rcmdcheck 46 | needs: check 47 | 48 | - uses: r-lib/actions/check-r-package@v2 49 | with: 50 | upload-snapshots: true 51 | -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, dev] 6 | pull_request: 7 | branches: [main, dev] 8 | 9 | name: lint 10 | 11 | jobs: 12 | lint: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | - uses: r-lib/actions/setup-r@v2 20 | with: 21 | use-public-rspm: true 22 | 23 | - uses: r-lib/actions/setup-r-dependencies@v2 24 | with: 25 | extra-packages: any::lintr, local::. 26 | needs: lint 27 | 28 | - name: Lint 29 | run: | 30 | library(lintr) 31 | style_rules <- list( 32 | absolute_path_linter(), assignment_linter(), brace_linter(), 33 | commas_linter(), commented_code_linter(), 34 | equals_na_linter(), function_left_parentheses_linter(), 35 | infix_spaces_linter(), whitespace_linter(), 36 | nonportable_path_linter(), 37 | pipe_continuation_linter(), seq_linter(), quotes_linter(), 38 | spaces_inside_linter(), spaces_left_parentheses_linter(), 39 | T_and_F_symbol_linter(), todo_comment_linter(), 40 | trailing_blank_lines_linter(), trailing_whitespace_linter(), 41 | unnecessary_concatenation_linter() 42 | ) 43 | excluded_files <- c("data-raw/", "R/RcppExports.R", "tests/") 44 | lint_package(linters = style_rules, exclusions = excluded_files) 45 | shell: Rscript {0} 46 | env: 47 | LINTR_ERROR_ON_LINT: true 48 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | steps: 23 | - uses: actions/checkout@v2 24 | 25 | - uses: r-lib/actions/setup-pandoc@v2 26 | 27 | - uses: r-lib/actions/setup-r@v2 28 | with: 29 | use-public-rspm: true 30 | 31 | - uses: r-lib/actions/setup-r-dependencies@v2 32 | with: 33 | extra-packages: any::pkgdown, local::. 34 | needs: website 35 | 36 | - name: Build site 37 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 38 | shell: Rscript {0} 39 | 40 | - name: Deploy to GitHub pages 🚀 41 | if: github.event_name != 'pull_request' 42 | uses: JamesIves/github-pages-deploy-action@4.1.4 43 | with: 44 | clean: false 45 | branch: gh-pages 46 | folder: docs 47 | -------------------------------------------------------------------------------- /.github/workflows/rhub.yaml: -------------------------------------------------------------------------------- 1 | # R-hub's generic GitHub Actions workflow file. It's canonical location is at 2 | # https://github.com/r-hub/actions/blob/v1/workflows/rhub.yaml 3 | # You can update this file to a newer version using the rhub2 package: 4 | # 5 | # rhub::rhub_setup() 6 | # 7 | # It is unlikely that you need to modify this file manually. 8 | 9 | name: R-hub 10 | run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}" 11 | 12 | on: 13 | workflow_dispatch: 14 | inputs: 15 | config: 16 | description: 'A comma separated list of R-hub platforms to use.' 17 | type: string 18 | default: 'linux,windows,macos' 19 | name: 20 | description: 'Run name. You can leave this empty now.' 21 | type: string 22 | id: 23 | description: 'Unique ID. You can leave this empty now.' 24 | type: string 25 | 26 | jobs: 27 | 28 | setup: 29 | runs-on: ubuntu-latest 30 | outputs: 31 | containers: ${{ steps.rhub-setup.outputs.containers }} 32 | platforms: ${{ steps.rhub-setup.outputs.platforms }} 33 | 34 | steps: 35 | # NO NEED TO CHECKOUT HERE 36 | - uses: r-hub/actions/setup@v1 37 | with: 38 | config: ${{ github.event.inputs.config }} 39 | id: rhub-setup 40 | 41 | linux-containers: 42 | needs: setup 43 | if: ${{ needs.setup.outputs.containers != '[]' }} 44 | runs-on: ubuntu-latest 45 | name: ${{ matrix.config.label }} 46 | strategy: 47 | fail-fast: false 48 | matrix: 49 | config: ${{ fromJson(needs.setup.outputs.containers) }} 50 | 51 | steps: 52 | - uses: r-hub/actions/checkout@v1 53 | 54 | - name: Install R 55 | uses: r-lib/actions/setup-r@v2 56 | 57 | - name: Install system dependencies 58 | run: | 59 | sudo apt-get update 60 | sudo apt-get install -y libcurl4-openssl-dev libssl-dev libxml2-dev 61 | 62 | 63 | 64 | 65 | - uses: r-hub/actions/platform-info@v1 66 | with: 67 | token: ${{ secrets.RHUB_TOKEN }} 68 | job-config: ${{ matrix.config.job-config }} 69 | - uses: r-hub/actions/setup-deps@v1 70 | with: 71 | token: ${{ secrets.RHUB_TOKEN }} 72 | job-config: ${{ matrix.config.job-config }} 73 | - uses: r-hub/actions/run-check@v1 74 | with: 75 | token: ${{ secrets.RHUB_TOKEN }} 76 | job-config: ${{ matrix.config.job-config }} 77 | 78 | other-platforms: 79 | needs: setup 80 | if: ${{ needs.setup.outputs.platforms != '[]' }} 81 | runs-on: ${{ matrix.config.os }} 82 | name: ${{ matrix.config.label }} 83 | strategy: 84 | fail-fast: false 85 | matrix: 86 | config: ${{ fromJson(needs.setup.outputs.platforms) }} 87 | 88 | steps: 89 | - uses: r-hub/actions/checkout@v1 90 | - uses: r-hub/actions/setup-r@v1 91 | with: 92 | job-config: ${{ matrix.config.job-config }} 93 | token: ${{ secrets.RHUB_TOKEN }} 94 | - uses: r-hub/actions/platform-info@v1 95 | with: 96 | token: ${{ secrets.RHUB_TOKEN }} 97 | job-config: ${{ matrix.config.job-config }} 98 | - uses: r-hub/actions/setup-deps@v1 99 | with: 100 | job-config: ${{ matrix.config.job-config }} 101 | token: ${{ secrets.RHUB_TOKEN }} 102 | - uses: r-hub/actions/run-check@v1 103 | with: 104 | job-config: ${{ matrix.config.job-config }} 105 | token: ${{ secrets.RHUB_TOKEN }} 106 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: any::covr 27 | needs: coverage 28 | 29 | - name: Test coverage 30 | run: | 31 | covr::codecov( 32 | quiet = FALSE, 33 | clean = FALSE, 34 | install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package") 35 | ) 36 | shell: Rscript {0} 37 | 38 | - name: Show testthat output 39 | if: always() 40 | run: | 41 | ## -------------------------------------------------------------------- 42 | find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true 43 | shell: bash 44 | 45 | - name: Upload test results 46 | if: failure() 47 | uses: actions/upload-artifact@v3 48 | with: 49 | name: coverage-test-failures 50 | path: ${{ runner.temp }}/package 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | 8 | # User-specific files 9 | .Ruserdata 10 | 11 | # Example code in package build process 12 | *-Ex.R 13 | 14 | # Output files from R CMD build 15 | /*.tar.gz 16 | 17 | # Output files from R CMD check 18 | /*.Rcheck/ 19 | 20 | # RStudio files 21 | .Rproj.user/ 22 | 23 | # produced vignettes 24 | vignettes/*.html 25 | vignettes/*.pdf 26 | 27 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 28 | .httr-oauth 29 | 30 | # knitr and R markdown default cache directories 31 | *_cache/ 32 | /cache/ 33 | 34 | # Temporary files created by R markdown 35 | *.utf8.md 36 | *.knit.md 37 | 38 | # R Environment Variables 39 | .Renviron 40 | .Rproj.user 41 | inst/doc 42 | docs 43 | 44 | # Plots from tests 45 | tests/testthat/*.pdf 46 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: galamm 2 | Title: Generalized Additive Latent and Mixed Models 3 | Version: 0.2.2 4 | Authors@R: c( 5 | person(given = "Øystein", 6 | family = "Sørensen", 7 | role = c("aut", "cre"), 8 | email = "oystein.sorensen@psykologi.uio.no", 9 | comment = c(ORCID = "0000-0003-0724-3542")), 10 | person(given = "Douglas", family = "Bates", role = "ctb"), 11 | person(given = "Ben", family = "Bolker", role = "ctb"), 12 | person(given = "Martin", family = "Maechler", role = "ctb"), 13 | person(given = "Allan", family = "Leal", role = "ctb"), 14 | person(given = "Fabian", family = "Scheipl", role = "ctb"), 15 | person(given = "Steven", family = "Walker", role = "ctb"), 16 | person(given = "Simon", family = "Wood", role = "ctb") 17 | ) 18 | Description: Estimates generalized additive latent and 19 | mixed models using maximum marginal likelihood, 20 | as defined in Sorensen et al. (2023) 21 | , which is an extension of Rabe-Hesketh and 22 | Skrondal (2004)'s unifying framework for multilevel latent variable 23 | modeling . Efficient computation is done using sparse 24 | matrix methods, Laplace approximation, and automatic differentiation. The 25 | framework includes generalized multilevel models with heteroscedastic 26 | residuals, mixed response types, factor loadings, smoothing splines, 27 | crossed random effects, and combinations thereof. Syntax for model 28 | formulation is close to 'lme4' (Bates et al. (2015) 29 | ) and 'PLmixed' (Rockwood and Jeon (2019) 30 | ). 31 | License: GPL (>= 3) 32 | URL: https://github.com/LCBC-UiO/galamm, https://lcbc-uio.github.io/galamm/ 33 | BugReports: https://github.com/LCBC-UiO/galamm/issues 34 | Encoding: UTF-8 35 | Imports: 36 | lme4, 37 | Matrix, 38 | memoise, 39 | methods, 40 | mgcv, 41 | nlme, 42 | Rcpp, 43 | Rdpack, 44 | stats 45 | Depends: 46 | R (>= 3.5.0) 47 | LinkingTo: 48 | Rcpp, 49 | RcppEigen 50 | LazyData: true 51 | Roxygen: list(markdown = TRUE, roclets = c ("namespace", "rd", "srr::srr_stats_roclet")) 52 | RoxygenNote: 7.3.2 53 | Suggests: 54 | covr, 55 | gamm4, 56 | knitr, 57 | PLmixed, 58 | rmarkdown, 59 | testthat (>= 3.0.0) 60 | Config/testthat/edition: 3 61 | VignetteBuilder: knitr, rmarkdown 62 | RdMacros: Rdpack 63 | NeedsCompilation: yes 64 | SystemRequirements: C++17 65 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(VarCorr,galamm) 4 | S3method(anova,galamm) 5 | S3method(coef,galamm) 6 | S3method(confint,galamm) 7 | S3method(deviance,galamm) 8 | S3method(extract_optim_parameters,galamm) 9 | S3method(factor_loadings,galamm) 10 | S3method(family,galamm) 11 | S3method(fitted,galamm) 12 | S3method(fixef,galamm) 13 | S3method(formula,galamm) 14 | S3method(logLik,galamm) 15 | S3method(nobs,galamm) 16 | S3method(plot,galamm) 17 | S3method(plot_smooth,galamm) 18 | S3method(predict,galamm) 19 | S3method(print,VarCorr.galamm) 20 | S3method(print,galamm) 21 | S3method(print,summary.galamm) 22 | S3method(ranef,galamm) 23 | S3method(residuals,galamm) 24 | S3method(sigma,galamm) 25 | S3method(summary,galamm) 26 | S3method(vcov,galamm) 27 | export(VarCorr) 28 | export(extract_optim_parameters) 29 | export(factor_loadings) 30 | export(fixef) 31 | export(galamm) 32 | export(galamm_control) 33 | export(plot_smooth) 34 | export(ranef) 35 | export(response) 36 | export(s) 37 | export(sl) 38 | export(t2) 39 | export(t2l) 40 | importFrom(Rcpp,sourceCpp) 41 | importFrom(Rdpack,reprompt) 42 | importFrom(mgcv,s) 43 | importFrom(mgcv,t2) 44 | importFrom(nlme,VarCorr) 45 | importFrom(nlme,fixef) 46 | importFrom(nlme,ranef) 47 | importFrom(stats,anova) 48 | importFrom(stats,coef) 49 | importFrom(stats,deviance) 50 | importFrom(stats,family) 51 | importFrom(stats,fitted) 52 | importFrom(stats,formula) 53 | importFrom(stats,gaussian) 54 | importFrom(stats,logLik) 55 | importFrom(stats,nobs) 56 | importFrom(stats,predict) 57 | importFrom(stats,residuals) 58 | importFrom(stats,sigma) 59 | importFrom(stats,vcov) 60 | useDynLib(galamm, .registration = TRUE) 61 | -------------------------------------------------------------------------------- /R/VarCorr.R: -------------------------------------------------------------------------------- 1 | ##' @importFrom nlme VarCorr 2 | ##' @export VarCorr 3 | NULL 4 | 5 | #' @title Extract variance and correlation components from model 6 | #' 7 | #' @srrstats {G1.4} Function documented with roxygen2. 8 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 9 | #' 10 | #' @param x An object of class \code{galamm} returned from \code{\link{galamm}}. 11 | #' @param sigma Numeric value used to multiply the standard deviations. Defaults 12 | #' to 1. 13 | #' @param ... Other arguments passed onto other methods. Currently not used. 14 | #' 15 | #' @name VarCorr 16 | #' @aliases VarCorr VarCorr.galamm 17 | #' 18 | #' @return An object of class \code{c("VarCorr.galamm", "VarCorr.merMod")}. 19 | #' @export 20 | #' 21 | #' @seealso [print.VarCorr.galamm()] for the print function. 22 | #' 23 | #' @family details of model fit 24 | #' 25 | #' @examples 26 | #' # Linear mixed model with heteroscedastic residuals 27 | #' mod <- galamm( 28 | #' formula = y ~ x + (1 | id), 29 | #' weights = ~ (1 | item), 30 | #' data = hsced 31 | #' ) 32 | #' 33 | #' # Extract information on variance and covariance 34 | #' VarCorr(mod) 35 | #' 36 | #' # Convert to data frame 37 | #' # (this invokes lme4's function as.data.frame.VarCorr.merMod) 38 | #' as.data.frame(VarCorr(mod)) 39 | #' 40 | VarCorr.galamm <- function(x, sigma = 1, ...) { 41 | useSc <- Reduce(function(`&&`, y) y$family == "gaussian", 42 | family(x), 43 | init = TRUE 44 | ) 45 | 46 | structure( 47 | lme4::mkVarCorr(sigma(x)[[1]], x$model$lmod$reTrms$cnms, 48 | nc = lengths(x$model$lmod$reTrms$cnms), 49 | theta = x$parameters$parameter_estimates[x$parameters$theta_inds], 50 | names(x$model$lmod$reTrms$cnms) 51 | ), 52 | useSc = useSc, 53 | class = c("VarCorr.galamm", "VarCorr.merMod") 54 | ) 55 | } 56 | 57 | 58 | #' @title Print method for variance-covariance objects 59 | #' 60 | #' @srrstats {G1.4} Function documented with roxygen2. 61 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 62 | #' @srrstats {G2.3,G2.3a} match.arg() used on "comp" argument. 63 | #' @srrstats {G2.3,G2.3b} Argument "comp" is case sensitive, as is documented here. 64 | #' 65 | #' @param x An object of class \code{c("VarCorr.galamm", "VarCorr.merMod")}, 66 | #' returned from \code{\link{VarCorr.galamm}}. 67 | #' @param digits Optional arguments specifying number of digits to use when 68 | #' printing. 69 | #' @param comp Character vector of length 1 or 2 specifying which variance 70 | #' components to print. Case sensitive. Can take one of the values "Std.Dev." 71 | #' and "Variance". 72 | #' @param corr Logical value indicating whether covariances or correlations 73 | #' should be printed. 74 | #' @param ... Optional arguments passed on to other methods. Currently not used. 75 | #' 76 | #' @return The variance-covariance information is printed to the console and the 77 | #' argument \code{x} is silently returned. 78 | #' @export 79 | #' 80 | #' @author This function is derived from \code{lme4:::print.VarCorr.merMod} 81 | #' written by Douglas M. Bates, Martin Maechler, Ben Bolker, and Steve Walker. 82 | #' 83 | #' @references \insertRef{batesFittingLinearMixedEffects2015}{galamm} 84 | #' 85 | #' @seealso [VarCorr.galamm()] for the function creating the variance-covariance 86 | #' objects. 87 | #' 88 | #' @family details of model fit 89 | #' 90 | #' @examples 91 | #' # Linear mixed model with heteroscedastic residuals 92 | #' mod <- galamm( 93 | #' formula = y ~ x + (1 | id), 94 | #' weights = ~ (1 | item), 95 | #' data = hsced 96 | #' ) 97 | #' 98 | #' # Extract information on variance and covariance 99 | #' VarCorr(mod) 100 | #' 101 | print.VarCorr.galamm <- function(x, digits = max(3, getOption("digits") - 2), 102 | comp = c("Std.Dev.", "Variance"), 103 | corr = any(comp == "Std.Dev."), ...) { 104 | comp <- match.arg(comp, several.ok = TRUE) 105 | print(lme4::formatVC(x, digits = digits, comp = comp, corr = corr), 106 | quote = FALSE, ... 107 | ) 108 | invisible(x) 109 | } 110 | -------------------------------------------------------------------------------- /R/coef.R: -------------------------------------------------------------------------------- 1 | #' @title Extract galamm coefficients 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 5 | #' @srrstats {RE4.2} Model coefficients (via coef() / coefficients()) 6 | #' 7 | #' @description 8 | #' Currently, this function only returns the fixed effects. 9 | #' 10 | #' @param object An object of class \code{galamm}, from \code{\link{galamm}}. 11 | #' @param ... Optional arguments passed on to other methods. Currently not used. 12 | #' 13 | #' @return A matrix with the requested coefficients. 14 | #' @export 15 | #' 16 | #' 17 | #' @seealso [fixef.galamm()] for fixed effects, [ranef.galamm()] for random 18 | #' effects, and [coef()] for the generic function. 19 | #' 20 | #' @family details of model fit 21 | #' 22 | #' @examples 23 | #' # Poisson GLMM 24 | #' count_mod <- galamm( 25 | #' formula = y ~ lbas * treat + lage + v4 + (1 | subj), 26 | #' data = epilep, family = poisson 27 | #' ) 28 | #' 29 | #' # Extract coefficients 30 | #' coef(count_mod) 31 | #' 32 | coef.galamm <- function(object, ...) { 33 | fixef(object) 34 | } 35 | -------------------------------------------------------------------------------- /R/confint.R: -------------------------------------------------------------------------------- 1 | #' @title Confidence intervals for model parameters 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.3,G2.3a} match.arg() used on "method" argument. 5 | #' @srrstats {G2.3,G2.3b} Arguments parm and method are case sensitive, as stated in 6 | #' their documentation. 7 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 8 | #' @srrstats {RE4.3} Confidence intervals on those coefficients (via confint()) 9 | #' 10 | #' @param object An object of class \code{galamm} returned from 11 | #' \code{\link{galamm}}. 12 | #' @param parm Parameters for which to compute intervals. Use \code{"theta"} to 13 | #' get all variance parameters, \code{"beta"} to get all fixed regression 14 | #' coefficients, \code{"lambda"} to get all factor loadings, and 15 | #' \code{"weights"} to get all weights. The parameter can also be given as a 16 | #' numeric vector with indices specifying the parameters. When given as 17 | #' characters, the arguments are case sensitive. 18 | #' @param level Decimal number specifying the confidence level. Defaults to 0.95. 19 | #' @param method Character of length one specifying the type of confidence 20 | #' interval. Currently only "Wald" is available. The argument is case 21 | #' sensitive. 22 | #' @param ... Other arguments passed on to other methods. Currently not used. 23 | #' 24 | #' @return A matrix with the requested confidence intervals. 25 | #' @export 26 | #' 27 | #' 28 | #' @seealso [fixef.galamm()] for fixed effects, [coef.galamm()] for coefficients 29 | #' more generally, and [vcov.galamm()] for the variance-covariance matrix. 30 | #' [confint()] is the generic function. 31 | #' 32 | #' @family details of model fit 33 | #' 34 | #' @examples 35 | #' # Poisson GLMM 36 | #' count_mod <- galamm( 37 | #' formula = y ~ lbas * treat + lage + v4 + (1 | subj), 38 | #' data = epilep, family = poisson 39 | #' ) 40 | #' 41 | #' confint(count_mod, parm = "beta", level = .99) 42 | #' 43 | confint.galamm <- function(object, parm, level = 0.95, 44 | method = "Wald", ...) { 45 | method <- match.arg(method, "Wald") 46 | stopifnot(length(level) == 1 && level > 0 && level < 1) 47 | 48 | inds <- find_parm_inds(object, parm) 49 | 50 | cf <- object$parameters$parameter_estimates[inds] 51 | ses <- sqrt(diag(vcov(object, parm))) 52 | 53 | a <- (1 - level) / 2 54 | a <- c(a, 1 - a) 55 | fac <- stats::qnorm(a) 56 | pct <- paste( 57 | format(100 * a, trim = TRUE, scientific = FALSE, digits = 3), "%" 58 | ) 59 | ci <- array(NA_real_, 60 | dim = c(length(inds), 2L), 61 | dimnames = list(inds, pct) 62 | ) 63 | ci[] <- cf + ses %o% fac 64 | rownames(ci) <- object$parameters$parameter_names[inds] 65 | ci 66 | } 67 | -------------------------------------------------------------------------------- /R/extract_optim_parameters.R: -------------------------------------------------------------------------------- 1 | extract_optim_parameters <- function(object) { 2 | UseMethod("extract_optim_parameters") 3 | } 4 | 5 | #' @title Extract parameters from fitted model for use as initial values 6 | #' 7 | #' @srrstats {G1.4} Function documented with roxygen2. 8 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 9 | #' 10 | #' @description This function extracts parameter values from a fitted model object in a form 11 | #' that can be directly provided as initial values for a new model fit. 12 | #' 13 | #' @aliases extract_optim_parameters extract_optim_parameters.galamm 14 | #' @export extract_optim_parameters 15 | #' @export 16 | #' 17 | #' @param object Object of class \code{galamm} returned from 18 | #' \code{\link{galamm}}. 19 | #' 20 | #' @return A \code{list} object containing the following elements: 21 | #' * \code{theta} Numerical vector of variance components, i.e., entries of 22 | #' the lower Cholesky form of the covariance matrix of random effects. 23 | #' * \code{beta} Fixed regression coefficients. 24 | #' * \code{lambda} Factor loadings. 25 | #' * \code{weights} Weights for heteroscedastic residuals. 26 | #' 27 | #' 28 | #' @family optimization functions 29 | #' 30 | #' @examples 31 | #' # Fit linear mixed model with heteroscedastic residuals 32 | #' mod <- galamm( 33 | #' formula = y ~ x + (1 | id), 34 | #' weights = ~ (1 | item), 35 | #' data = hsced 36 | #' ) 37 | #' 38 | #' # Extract parameters 39 | #' start <- extract_optim_parameters(mod) 40 | #' 41 | #' # Fit again using the Nelder-Mead algorithm, using start as initial values: 42 | #' mod_nm <- galamm( 43 | #' formula = y ~ x + (1 | id), 44 | #' weights = ~ (1 | item), 45 | #' data = hsced, 46 | #' start = start, 47 | #' control = galamm_control(method = "Nelder-Mead") 48 | #' ) 49 | #' 50 | extract_optim_parameters.galamm <- function(object) { 51 | list( 52 | theta = object$parameters$parameter_estimates[ 53 | object$parameters$theta_inds 54 | ], 55 | beta = object$parameters$parameter_estimates[ 56 | object$parameters$beta_inds 57 | ], 58 | lambda = object$parameters$parameter_estimates[ 59 | c( 60 | object$parameters$lambda_inds, 61 | object$parameters$lambda_interaction_inds 62 | ) 63 | ], 64 | weights = object$parameters$parameter_estimates[ 65 | object$parameters$weights_inds 66 | ] 67 | ) 68 | } 69 | -------------------------------------------------------------------------------- /R/factor_loadings.R: -------------------------------------------------------------------------------- 1 | factor_loadings <- function(object) { 2 | UseMethod("factor_loadings") 3 | } 4 | 5 | #' @title Extract factor loadings from galamm object 6 | #' 7 | #' @aliases factor_loadings factor_loadings.galamm 8 | #' @export factor_loadings 9 | #' @export 10 | #' 11 | #' @srrstats {G1.4} Function documented with roxygen2. 12 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 13 | #' @srrstats {G2.4,G2.4c} as.character() used to define dimnames of the returned 14 | #' object. 15 | #' 16 | #' @param object Object of class \code{galamm} returned from 17 | #' \code{\link{galamm}}. 18 | #' 19 | #' @return A matrix containing the estimated factor loadings with corresponding 20 | #' standard deviations. 21 | #' 22 | #' @details This function has been named \code{factor_loadings} rather than just 23 | #' \code{loadings} to avoid conflict with \code{stats::loadings}. 24 | #' 25 | #' @seealso [fixef.galamm()] for fixed regression coefficients, 26 | #' [confint.galamm()] for confidence intervals, and [coef.galamm()] for 27 | #' coefficients more generally. 28 | #' 29 | #' @author The example for this function comes from \code{PLmixed}, with authors 30 | #' Nicholas Rockwood and Minjeong Jeon 31 | #' \insertCite{rockwoodEstimatingComplexMeasurement2019}{galamm}. 32 | #' 33 | #' @family details of model fit 34 | #' 35 | #' @examples 36 | #' # Logistic mixed model with factor loadings, example from PLmixed 37 | #' data("IRTsim", package = "PLmixed") 38 | #' 39 | #' # Reduce data size for the example to run faster 40 | #' IRTsub <- IRTsim[IRTsim$item < 4, ] 41 | #' IRTsub <- IRTsub[sample(nrow(IRTsub), 300), ] 42 | #' IRTsub$item <- factor(IRTsub$item) 43 | #' 44 | #' # Fix loading for first item to 1, and estimate the two others freely 45 | #' loading_matrix <- matrix(c(1, NA, NA), ncol = 1) 46 | #' 47 | #' # Estimate model 48 | #' mod <- galamm(y ~ item + (0 + ability | sid) + (0 + ability | school), 49 | #' data = IRTsub, family = binomial, load.var = "item", 50 | #' factor = "ability", lambda = loading_matrix 51 | #' ) 52 | #' 53 | #' # Show estimated factor loadings, with standard errors 54 | #' factor_loadings(mod) 55 | #' 56 | factor_loadings.galamm <- function(object) { 57 | if (is.null(object$parameters$lambda_dummy)) { 58 | return(invisible(NULL)) 59 | } 60 | 61 | lambda_tmp_est <- lambda_tmp_se <- object$parameters$lambda_dummy 62 | lambda_tmp_se[lambda_tmp_se %in% c(0, 1)] <- NA_real_ 63 | 64 | lambda_tmp_est[lambda_tmp_est > 1] <- 65 | object$parameters$parameter_estimates[object$parameters$lambda_inds] 66 | lambda_tmp_se[!is.na(lambda_tmp_se)] <- 67 | sqrt(diag(vcov(object, parm = "lambda"))) 68 | 69 | nn <- nrow(object$parameters$lambda_dummy) 70 | ret <- matrix(rbind(lambda_tmp_est, lambda_tmp_se), 71 | nrow = nrow(lambda_tmp_est), 72 | dimnames = list( 73 | paste0("lambda", seq_len(nn)), 74 | as.character(rbind(colnames(lambda_tmp_est), "SE")) 75 | ) 76 | ) 77 | 78 | lix <- length(object$parameters$lambda_interaction_inds) 79 | if (lix > 0) { 80 | vars <- unlist(lapply(object$model$factor_interactions, function(x) { 81 | attr(stats::terms(x), "term.labels") 82 | })) 83 | 84 | ret2 <- matrix( 85 | c( 86 | object$parameters$parameter_estimates[ 87 | object$parameters$lambda_interaction_inds 88 | ], 89 | sqrt(diag(vcov(object, parm = "lambda_interaction"))) 90 | ), 91 | nrow = lix 92 | ) 93 | rownames(ret2) <- paste0( 94 | "lambda", seq(from = nn + 1, length.out = lix), 95 | "_", vars 96 | ) 97 | 98 | ret <- rbind(ret, ret2) 99 | } 100 | ret 101 | } 102 | -------------------------------------------------------------------------------- /R/family.R: -------------------------------------------------------------------------------- 1 | #' @title Extract family or families from fitted galamm 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 5 | #' @description 6 | #' This function returns a list of families for an object of class 7 | #' \code{galamm}, returned from \code{\link{galamm}}. 8 | #' 9 | #' @param object An object of class \code{galamm} returned from 10 | #' \code{\link{galamm}}. 11 | #' @param ... Optional arguments passed on to other methods. Currently not used. 12 | #' 13 | #' @return A list of family objects. 14 | #' @export 15 | #' 16 | #' @seealso [galamm()] 17 | #' 18 | #' @family details of model fit 19 | #' 20 | #' @examples 21 | #' # Mixed response model 22 | #' loading_matrix <- matrix(c(1, NA), ncol = 1) 23 | #' families <- c(gaussian, binomial) 24 | #' family_mapping <- ifelse(mresp$itemgroup == "a", 1, 2) 25 | #' 26 | #' mixed_resp <- galamm( 27 | #' formula = y ~ x + (0 + level | id), 28 | #' data = mresp, 29 | #' family = families, 30 | #' family_mapping = family_mapping, 31 | #' load.var = "itemgroup", 32 | #' lambda = loading_matrix, 33 | #' factor = "level" 34 | #' ) 35 | #' 36 | #' # This model has two family objects 37 | #' family(mixed_resp) 38 | #' 39 | family.galamm <- function(object, ...) { 40 | object$model$family 41 | } 42 | -------------------------------------------------------------------------------- /R/fitted.galamm.R: -------------------------------------------------------------------------------- 1 | #' @title Extract model fitted values 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 5 | #' @srrstats {RE4.9} Modelled values of response variables. 6 | #' 7 | #' @description 8 | #' Extracts fitted values from a model including random effects. 9 | #' 10 | #' @param object An object of class \code{galamm} returned from 11 | #' \code{\link{galamm}}. 12 | #' @param ... Optional arguments passed on to other methods. Currently not used. 13 | #' 14 | #' 15 | #' @return A numerical vector with fit values for each row in the input data. 16 | #' @export 17 | #' 18 | #' @family details of model fit 19 | #' 20 | #' @examples 21 | #' # Linear mixed model with heteroscedastic residuals 22 | #' mod <- galamm( 23 | #' formula = y ~ x + (1 | id), 24 | #' weights = ~ (1 | item), 25 | #' data = hsced 26 | #' ) 27 | #' 28 | #' # Extract fitted values and plot against x 29 | #' plot(hsced$x, fitted(mod)) 30 | #' 31 | fitted.galamm <- function(object, ...) { 32 | object$model$fit 33 | } 34 | -------------------------------------------------------------------------------- /R/fixef.R: -------------------------------------------------------------------------------- 1 | ##' @importFrom nlme fixef 2 | ##' @export fixef 3 | NULL 4 | 5 | #' @title Extract fixed effects from galamm objects 6 | #' @srrstats {G1.4} Function documented with roxygen2. 7 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 8 | #' 9 | #' @description 10 | #' Extract the fixed regression coefficients. 11 | #' 12 | #' @param object An object of class \code{galamm}, returned from 13 | #' \code{\link{galamm}}. 14 | #' @param ... Optional arguments passed on to other methods. Currently not used. 15 | #' 16 | #' 17 | #' @return A named \code{numeric} vector containing the requested fixed effects. 18 | #' 19 | #' @name fixef 20 | #' @aliases fixef fixef.galamm 21 | #' @export 22 | #' 23 | #' @seealso [ranef.galamm()] for random effects, [coef.galamm()] for 24 | #' coefficients more generally, and [confint.galamm()] for confidence intervals. 25 | #' 26 | #' @family details of model fit 27 | #' 28 | #' @examples 29 | #' # Poisson GLMM 30 | #' count_mod <- galamm( 31 | #' formula = y ~ lbas * treat + lage + v4 + (1 | subj), 32 | #' data = epilep, family = poisson 33 | #' ) 34 | #' 35 | #' # Extract fixed effects 36 | #' fixef(count_mod) 37 | #' 38 | fixef.galamm <- function(object, ...) { 39 | ret <- object$parameters$parameter_estimates[object$parameters$beta_inds] 40 | names(ret) <- object$parameters$parameter_names[object$parameters$beta_inds] 41 | ret 42 | } 43 | -------------------------------------------------------------------------------- /R/formula.R: -------------------------------------------------------------------------------- 1 | #' @title Extract formula from fitted galamm object 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {RE4.4} The specification of the model, generally as a formula (via formula()) 5 | #' @param x Object of class \code{galamm} returned from \code{\link{galamm}}. 6 | #' @param ... Optional arguments passed on to other methods. Currently not used. 7 | #' 8 | #' @return The formula used to fit the model. 9 | #' @export 10 | #' 11 | #' @family details of model fit 12 | #' 13 | #' @examples 14 | #' # Mixed response model ------------------------------------------------------ 15 | #' 16 | #' # The mresp dataset contains a mix of binomial and Gaussian responses. 17 | #' 18 | #' # We need to estimate a factor loading which scales the two response types. 19 | #' loading_matrix <- matrix(c(1, NA), ncol = 1) 20 | #' 21 | #' # Define mapping to families. 22 | #' families <- c(gaussian, binomial) 23 | #' family_mapping <- ifelse(mresp$itemgroup == "a", 1, 2) 24 | #' 25 | #' 26 | #' # Fit the model 27 | #' mod <- galamm( 28 | #' formula = y ~ x + (0 + level | id), 29 | #' data = mresp, 30 | #' family = families, 31 | #' family_mapping = family_mapping, 32 | #' factor = "level", 33 | #' load.var = "itemgroup", 34 | #' lambda = loading_matrix 35 | #' ) 36 | #' 37 | #' # Formula 38 | #' formula(mod) 39 | #' 40 | formula.galamm <- function(x, ...) { 41 | x$call$formula 42 | } 43 | -------------------------------------------------------------------------------- /R/galamm-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | #' @aliases galamm-package NULL 3 | #' 4 | #' @references 5 | #' 6 | #' \insertRef{sorensenLongitudinalModelingAgeDependent2023}{galamm} 7 | #' 8 | "_PACKAGE" 9 | 10 | ## usethis namespace: start 11 | #' @useDynLib galamm, .registration = TRUE 12 | ## usethis namespace: end 13 | NULL 14 | 15 | ## usethis namespace: start 16 | #' @importFrom Rcpp sourceCpp 17 | #' @importFrom stats anova coef deviance family fitted formula gaussian logLik 18 | #' nobs predict residuals sigma vcov 19 | #' @importFrom Rdpack reprompt 20 | ## usethis namespace: end 21 | NULL 22 | -------------------------------------------------------------------------------- /R/logLik.galamm.R: -------------------------------------------------------------------------------- 1 | #' @title Extract Log-Likelihood of galamm Object 2 | #' @srrstats {G1.4} Function documented with roxygen2. 3 | #' @param object Object 4 | #' @param ... Other arguments 5 | #' 6 | #' @return Object of class \code{logLik} 7 | #' @export 8 | #' 9 | #' 10 | #' @seealso [deviance.galamm()] for a function returning deviance and 11 | #' [logLik()] for the generic function. 12 | #' 13 | #' @family details of model fit 14 | #' 15 | #' @examples 16 | #' # Linear mixed model with heteroscedastic residuals 17 | #' mod <- galamm( 18 | #' formula = y ~ x + (1 | id), 19 | #' weights = ~ (1 | item), 20 | #' data = hsced 21 | #' ) 22 | #' 23 | #' # Extract log likelihood 24 | #' logLik(mod) 25 | #' 26 | logLik.galamm <- function(object, ...) { 27 | structure( 28 | object$model$loglik, 29 | nobs = nobs(object), 30 | df = object$model$df, 31 | class = "logLik" 32 | ) 33 | } 34 | 35 | 36 | #' @title Extract deviance of galamm object 37 | #' 38 | #' @srrstats {G1.4} Function documented with roxygen2. 39 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 40 | #' 41 | #' @param object Object of class \code{galamm}, returned from 42 | #' \code{\link{galamm}}. 43 | #' @param ... Other arguments passed on to other methods. Currently not used. 44 | #' 45 | #' @return A numeric value giving the deviance of the model fit. 46 | #' @export 47 | #' 48 | #' @seealso [logLik.galamm()] for a function returning the log likelihood and 49 | #' [deviance()] for the generic function. 50 | #' 51 | #' @family details of model fit 52 | #' 53 | #' @examples 54 | #' # Linear mixed model with heteroscedastic residuals 55 | #' mod <- galamm( 56 | #' formula = y ~ x + (1 | id), 57 | #' weights = ~ (1 | item), 58 | #' data = hsced 59 | #' ) 60 | #' 61 | #' # Extract deviance 62 | #' deviance(mod) 63 | #' 64 | deviance.galamm <- function(object, ...) { 65 | object$model$deviance 66 | } 67 | -------------------------------------------------------------------------------- /R/plot.galamm.R: -------------------------------------------------------------------------------- 1 | #' @title Diagnostic plots for galamm objects 2 | #' 3 | #' @param x An object of class \code{galamm} returned from \code{\link{galamm}}. 4 | #' @param ... Optional arguments passed on to the \code{plot} function. 5 | #' 6 | #' @return A plot is displayed. 7 | #' @export 8 | #' 9 | #' @srrstats {G1.4} Function documented with roxygen2. 10 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 11 | #' @srrstats {RE6.0,RE6.2} Default plot method. 12 | #' @srrstats {RE6.1,RE6.3} Not applicable. 13 | #' 14 | #' @seealso [residuals.galamm()] for extracting residuals and [plot()] for the 15 | #' generic function. 16 | #' 17 | #' @family summary functions 18 | #' 19 | #' @examples 20 | #' # Linear mixed model example from lme4 21 | #' data("sleepstudy", package = "lme4") 22 | #' mod <- galamm(Reaction ~ Days + (Days | Subject), data = sleepstudy) 23 | #' 24 | #' # Diagnostic plot 25 | #' plot(mod) 26 | #' 27 | plot.galamm <- function(x, ...) { 28 | plot(fitted(x), residuals(x, type = "pearson"), 29 | xlab = "Predicted values", 30 | ylab = "Pearson residuals", 31 | ... 32 | ) 33 | graphics::abline(h = 0, col = "blue") 34 | } 35 | -------------------------------------------------------------------------------- /R/plot_smooth.R: -------------------------------------------------------------------------------- 1 | plot_smooth <- function(object, ...) { 2 | UseMethod("plot_smooth") 3 | } 4 | 5 | #' @title Plot smooth terms for galamm fits 6 | #' 7 | #' @srrstats {G1.4} Function documented with roxygen2. 8 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 9 | #' 10 | #' @description 11 | #' Plots smooth terms of a fitted \code{galamm} object. This function is a thin 12 | #' wrapper around \code{mgcv::plot.gam} 13 | #' \insertCite{woodGeneralizedAdditiveModels2017}{galamm}. 14 | #' 15 | #' @aliases plot_smooth plot_smooth.galamm 16 | #' @export plot_smooth 17 | #' @export 18 | #' 19 | #' @param object Object of class \code{galamm} returned from 20 | #' \code{\link{galamm}}. 21 | #' @param ... Other optional arguments, passed on to \code{mgcv::plot.gam}. 22 | #' 23 | #' @return A plot is displayed on the screen. 24 | #' @export 25 | #' 26 | #' @family summary functions 27 | #' 28 | #' @references \insertAllCited{} 29 | #' 30 | #' @examples 31 | #' # Generalized additive mixed model with factor structures ------------------- 32 | #' 33 | #' # The cognition dataset contains simulated measurements of three latent 34 | #' # time-dependent processes, corresponding to individuals' abilities in 35 | #' # cognitive domains. We focus here on the first domain, and take a single 36 | #' # random timepoint per person: 37 | #' dat <- subset(cognition, domain == 1) 38 | #' dat <- split(dat, f = dat$id) 39 | #' dat <- lapply(dat, function(x) x[x$timepoint %in% sample(x$timepoint, 1), ]) 40 | #' dat <- do.call(rbind, dat) 41 | #' dat$item <- factor(dat$item) 42 | #' 43 | #' # At each timepoint there are three items measuring ability in the cognitive 44 | #' # domain. We fix the factor loading for the first measurement to one, and 45 | #' # estimate the remaining two. This is specified in the loading matrix. 46 | #' loading_matrix <- matrix(c(1, NA, NA), ncol = 1) 47 | #' 48 | #' # We can now estimate the model. 49 | #' mod <- galamm( 50 | #' formula = y ~ 0 + item + sl(x, factor = "loading") + 51 | #' (0 + loading | id), 52 | #' data = dat, 53 | #' load.var = "item", 54 | #' lambda = loading_matrix, 55 | #' factor = "loading" 56 | #' ) 57 | #' 58 | #' # We can plot the estimated smooth term 59 | #' plot_smooth(mod, shade = TRUE) 60 | #' 61 | #' # We can turn off the rug at the bottom 62 | #' plot_smooth(mod, shade = TRUE, rug = FALSE) 63 | #' 64 | plot_smooth.galamm <- function(object, ...) { 65 | if (!exists("gam", object) || length(object$gam) == 0) { 66 | stop("No terms to plot.") 67 | } 68 | 69 | plot(object$gam, ...) 70 | } 71 | -------------------------------------------------------------------------------- /R/predict.galamm.R: -------------------------------------------------------------------------------- 1 | #' @title Predictions from a model at new data values 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 5 | #' @srrstats {G2.3,G2.3a} match.arg() used on "type" argument. 6 | #' @srrstats {G2.3,G2.3b} Argument "type" is case sensitive, which is documented. 7 | #' @srrstats {RE4.16} Submitting new groups yields population level prediction, 8 | #' which is the correct prediction for new groups in these models. 9 | #' 10 | #' @description Predictions are given at the population level, i.e., with random 11 | #' effects set to zero. For fitted models including random effects, see 12 | #' \code{\link{fitted.galamm}}. For mixed response models, only predictions on 13 | #' the scale of the linear predictors is supported. 14 | #' 15 | #' @param object An object of class \code{galamm} returned from 16 | #' \code{\link{galamm}}. 17 | #' @param newdata Data from for which to evaluate predictions, in a 18 | #' \code{data.frame}. Defaults to "NULL", which means that the predictions are 19 | #' evaluate at the data used to fit the model. 20 | #' @param type Character argument specifying the type of prediction object to be 21 | #' returned. Case sensitive. 22 | #' @param ... Optional arguments passed on to other methods. Currently used for 23 | #' models with smooth terms, for which these arguments are forwarded to 24 | #' \code{mgcv::predict.gam}. 25 | #' 26 | #' @return A numeric vector of predicted values. 27 | #' @export 28 | #' 29 | #' @seealso [fitted.galamm()] for model fits, [residuals.galamm()] for 30 | #' residuals, and [predict()] for the generic function. 31 | #' 32 | #' @family details of model fit 33 | #' 34 | #' @examples 35 | #' # Poisson GLMM 36 | #' count_mod <- galamm( 37 | #' formula = y ~ lbas * treat + lage + v4 + (1 | subj), 38 | #' data = epilep, family = poisson 39 | #' ) 40 | #' 41 | #' # Plot response versus link: 42 | #' plot( 43 | #' predict(count_mod, type = "link"), 44 | #' predict(count_mod, type = "response") 45 | #' ) 46 | #' 47 | #' # Predict on a new dataset 48 | #' nd <- data.frame(lbas = c(.3, .2), treat = c(0, 1), lage = 0.2, v4 = -.2) 49 | #' predict(count_mod, newdata = nd) 50 | #' predict(count_mod, newdata = nd, type = "response") 51 | #' 52 | predict.galamm <- function(object, newdata = NULL, 53 | type = c("link", "response"), 54 | ...) { 55 | type <- match.arg(type) 56 | 57 | if (!is.null(newdata)) { 58 | if (!is.null(object$gam) && length(object$gam) > 0) { 59 | return(predict(object$gam, newdata = newdata, type = type, ...)) 60 | } 61 | newform <- stats::update(lme4::nobars(eval(object$call[[2]])), NULL ~ .) 62 | X <- stats::model.matrix(newform, data = newdata) 63 | beta_hat <- 64 | object$parameters$parameter_estimates[object$parameters$beta_inds] 65 | 66 | linear_predictor <- X %*% beta_hat 67 | } else { 68 | if (!is.null(object$gam) && length(object$gam) > 0) { 69 | return(predict(object$gam, type = type, ...)) 70 | } 71 | linear_predictor <- family(object)[[1]]$linkfun(object$model$fit_population) 72 | } 73 | if (length(object$model$family) > 1 && type == "response") { 74 | stop("For mixed response model, only type='link' works.") 75 | } 76 | 77 | if (type == "response") { 78 | family(object)[[1]]$linkinv(linear_predictor) 79 | } else { 80 | linear_predictor 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /R/ranef.R: -------------------------------------------------------------------------------- 1 | ##' @importFrom nlme ranef 2 | ##' @export ranef 3 | NULL 4 | 5 | #' @title Extract random effects from galamm object. 6 | #' 7 | #' @srrstats {G1.4} Function documented with roxygen2. 8 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 9 | #' 10 | #' @param object An object of class \code{galamm}, returned from 11 | #' \code{\link{galamm}}. 12 | #' @param ... Optional parameters passed on to other methods. Currently not 13 | #' used. 14 | #' 15 | #' @return An object of class \code{ranef.galamm}, containing the requested 16 | #' random effects. 17 | #' 18 | #' @aliases ranef ranef.galamm 19 | #' 20 | #' @export 21 | #' 22 | #' @family details of model fit 23 | #' 24 | #' @author This function is derived from \code{lme4::ranef.merMod}, written by 25 | #' Douglas Bates, Martin Maechler, Ben Bolker, Steve Walker. 26 | #' 27 | #' @references \insertRef{batesFittingLinearMixedEffects2015}{galamm} 28 | #' 29 | #' @seealso [fixef.galamm()] for fixed effects and [coef.galamm()] for 30 | #' coefficients more generally. 31 | #' 32 | #' @examples 33 | #' # Poisson GLMM 34 | #' count_mod <- galamm( 35 | #' formula = y ~ lbas * treat + lage + v4 + (1 | subj), 36 | #' data = epilep, family = poisson 37 | #' ) 38 | #' 39 | #' # Extract random effects 40 | #' ranef(count_mod) 41 | #' 42 | ranef.galamm <- function(object, ...) { 43 | ans <- object$random_effects$b 44 | if (!is.null(fl <- object$model$lmod$reTrms$flist)) { 45 | ## evaluate the list of matrices 46 | levs <- lapply(fl, levels) 47 | asgn <- attr(fl, "assign") 48 | cnms <- object$model$lmod$reTrms$cnms 49 | nc <- lengths(cnms) ## number of terms 50 | 51 | nb <- diff(object$model$lmod$reTrms$Gp) 52 | nbseq <- rep.int(seq_along(nb), nb) 53 | ml <- split(ans, nbseq) 54 | for (i in seq_along(ml)) { 55 | ml[[i]] <- matrix(ml[[i]], 56 | ncol = nc[i], byrow = TRUE, 57 | dimnames = list(NULL, cnms[[i]]) 58 | ) 59 | } 60 | 61 | ans <- lapply( 62 | seq_along(fl), 63 | function(i) { 64 | m <- ml[asgn == i] 65 | b2 <- vapply(m, nrow, numeric(1)) 66 | ub2 <- unique(b2) 67 | rnms <- if (ub2 == length(levs[[i]])) levs[[i]] else seq(ub2) 68 | data.frame(do.call(cbind, m), 69 | row.names = rnms, 70 | check.names = FALSE 71 | ) 72 | } 73 | ) 74 | names(ans) <- names(fl) 75 | 76 | # Have to implement covariance matrix for random effects later 77 | 78 | class(ans) <- "ranef.galamm" 79 | } 80 | ans 81 | } 82 | -------------------------------------------------------------------------------- /R/residuals.galamm.R: -------------------------------------------------------------------------------- 1 | #' @title Residuals of galamm objects 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.3,G2.3a} match.arg() used on "type" argument. 5 | #' @srrstats {G2.3,G2.3b} Argument type is case sensitive, as stated in their 6 | #' documentation. 7 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 8 | #' @srrstats {RE4.10} Model Residuals, including sufficient documentation to 9 | #' enable interpretation of residuals, and to enable users to submit residuals 10 | #' to their own tests. 11 | #' 12 | #' @param object An object of class \code{galamm} returned from 13 | #' \code{\link{galamm}}. 14 | #' @param type Character of length one describing the type of residuals to be 15 | #' returned. One of \code{"pearson"} and \code{"deviance"}. Argument is case 16 | #' sensitive. 17 | #' @param ... Optional arguments passed on to other methods. Currently not used. 18 | #' 19 | #' @return Numeric vector of residual values. 20 | #' @export 21 | #' 22 | #' @seealso [fitted.galamm()] for model fitted values, [predict.galamm()] for 23 | #' model predictions, and [plot.galamm()] for diagnostic plots. The generic 24 | #' function is [residuals()]. 25 | #' 26 | #' @family details of model fit 27 | #' 28 | #' @examples 29 | #' # Poisson GLMM 30 | #' count_mod <- galamm( 31 | #' formula = y ~ lbas * treat + lage + v4 + (1 | subj), 32 | #' data = epilep, family = poisson 33 | #' ) 34 | #' 35 | #' # Extract residuals 36 | #' residuals(count_mod) 37 | #' 38 | residuals.galamm <- function(object, type = c("pearson", "deviance"), ...) { 39 | type <- match.arg(type, c("pearson", "deviance")) 40 | if (type == "pearson") { 41 | object$model$pearson_residuals 42 | } else if (type == "deviance") { 43 | object$model$deviance_residuals 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /R/response.R: -------------------------------------------------------------------------------- 1 | #' @title Extract response values 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 5 | #' @srrstats {RE4.8} Response variables, and associated "metadata" where 6 | #' applicable. 7 | #' 8 | #' @description Extracts response values from a model. 9 | #' 10 | #' @param object An object of class \code{galamm} returned from 11 | #' \code{\link{galamm}}. 12 | #' @param ... Optional arguments passed on to other methods. Currently not used. 13 | #' 14 | #' 15 | #' @return A numerical vector with fit response values for each row in the input 16 | #' data. 17 | #' @export 18 | #' 19 | #' @family details of model fit 20 | #' 21 | #' @examples 22 | #' # Linear mixed model with heteroscedastic residuals 23 | #' mod <- galamm( 24 | #' formula = y ~ x + (1 | id), 25 | #' weights = ~ (1 | item), 26 | #' data = hsced 27 | #' ) 28 | #' 29 | #' # Plot response versus fitted values 30 | #' plot(fitted(mod), response(mod)) 31 | #' 32 | response <- function(object, ...) { 33 | object$model$response 34 | } 35 | -------------------------------------------------------------------------------- /R/sigma.R: -------------------------------------------------------------------------------- 1 | #' @title Extract square root of dispersion parameter from galamm object 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 5 | #' 6 | #' @description 7 | #' Extracts the square root of the dispersion parameter(s) from an object of 8 | #' class \code{galamm}, returned from \code{\link{galamm}}. In the case of 9 | #' conditionally Gaussian responses, this is the residual standard deviation. 10 | #' When there are multiple dispersion parameters, e.g., with mixed response 11 | #' type models, the square root of all of them are returned in a numeric vector. 12 | #' 13 | #' @param object An object of class \code{galamm}, returned from 14 | #' \code{\link{galamm}}. 15 | #' @param ... Optional parameters passed on to other methods. Currently not 16 | #' used. 17 | #' 18 | #' @return The square root of one or more dispersion parameters. 19 | #' 20 | #' @seealso [galamm()] 21 | #' @export 22 | #' 23 | #' @family details of model fit 24 | #' 25 | #' @examples 26 | #' # Linear mixed model with heteroscedastic residuals 27 | #' mod <- galamm( 28 | #' formula = y ~ x + (1 | id), 29 | #' weights = ~ (1 | item), 30 | #' data = hsced 31 | #' ) 32 | #' 33 | #' # Extract residual standard deviation. 34 | #' sigma(mod) 35 | #' 36 | #' # The residual standard deviation applies to the base case. The variance 37 | #' # function shown in the model output shows the estimated multiplier for 38 | #' # various grouping levels: 39 | #' summary(mod) 40 | #' 41 | sigma.galamm <- function(object, ...) { 42 | sqrt(object$parameters$dispersion_parameter) 43 | } 44 | -------------------------------------------------------------------------------- /R/srr-stats-standards.R: -------------------------------------------------------------------------------- 1 | #' srr_stats 2 | #' 3 | #' All of the following standards initially have `@srrstatsTODO` tags. These may 4 | #' be moved at any time to any other locations in your code. Once addressed, 5 | #' please modify the tag from `@srrstatsTODO` to `@srrstats`, or `@srrstatsNA`, 6 | #' ensuring that references to every one of the following standards remain 7 | #' somewhere within your code. (These comments may be deleted at any time.) 8 | #' 9 | #' @srrstatsVerbose TRUE 10 | #' 11 | #' @srrstats {G1.2} Life cycle statement is in the file .github/CONTRIBUTING.md 12 | #' @srrstats {G1.5} No performance claims made in associated publication. Might 13 | #' be added in the future, if a publication is made based on this package. 14 | #' @srrstats {G2.4,G2.4e} No explicit conversion from factor to other types is done. 15 | #' @srrstats {G2.8} Not directly relevant. 16 | #' @srrstats {G2.9} I'm not aware of any conversions in which information is 17 | #' lost. 18 | #' @srrstats {G2.11} We do not rely on class attributes of columns, except for 19 | #' factors. 20 | #' @srrstats {G2.12} List columns are not supported. 21 | #' @srrstats {G2.14b} Ignoring missing data does not make sense mathematically, 22 | #' so option \code{na.action = "na.omit"} will cause an error, through 23 | #' match.arg(). 24 | #' @srrstats {G2.14c} Replacing missing values with properly imputed values is a 25 | #' modeling step in itself. For this to be valid, a model has to be fitted on 26 | #' each imputed dataset, and the estimates need to be combined. Users who want 27 | #' to do this, would need to set up the infrastructure themselves, potentially 28 | #' using the \code{mice} package. 29 | #' @srrstats {G3.0} No floating point numbers are compared for equality. 30 | #' @srrstats {G3.1} The \code{stats::cov} function is not used. In the models 31 | #' supported by \code{galamm}, the only easily available covariance matrix is 32 | #' the inverse of the Hessian of the marginal log-likelihood at the local 33 | #' optimum. This is the asymptotic covariance matrix. Other ways of computing 34 | #' covariance matrices are not within scope. 35 | #' @srrstats {G3.1a} No alternative covariance methods are supported. 36 | #' @srrstats {G4.0} Output written to local files is not supported. 37 | #' @srrstats {G5.4c} Code for original implementation in published paper is 38 | #' available at https://github.com/LCBC-UiO/galamm-scripts. The paper 39 | #' \insertCite{sorensenLongitudinalModelingAgeDependent2023;textual}{galamm} 40 | #' included extensive simulation experiments which suggested that the 41 | #' implementation was correct for the models considered there, and this code 42 | #' is available in the linked repository, including commit tag which can be 43 | #' used to install the galamm package as it was at the time of publication. 44 | #' @srrstats {G5.10} Environment variable GALAMM_EXTENDED_TESTS used. It 45 | #' can be triggered by adding "run-extended" in the Git commit message, in 46 | #' case of which it will be run on GitHub Actions. 47 | #' @srrstats {G5.11} No large datasets required for extended tests. 48 | #' @srrstats {G5.11a} No data for extended tests needs to be downloaded. 49 | #' @srrstats {G5.12} No special conditions necessary to run extended tests. 50 | #' @noRd 51 | NULL 52 | 53 | #' NA_standards 54 | #' 55 | #' 56 | #' Any non-applicable standards can have their tags changed from `@srrstatsTODO` 57 | #' to `@srrstatsNA`, and placed together in this block, along with explanations 58 | #' for why each of these standards have been deemed not applicable. 59 | #' (These comments may also be deleted at any time.) 60 | #' @noRd 61 | NULL 62 | -------------------------------------------------------------------------------- /R/vcov.R: -------------------------------------------------------------------------------- 1 | #' @title Calculate variance-covariance matrix for GALAMM fit 2 | #' 3 | #' @srrstats {G1.4} Function documented with roxygen2. 4 | #' @srrstats {G2.3,G2.3b} Argument "parm" is case sensitive, as is documented here. 5 | #' @srrstats {G2.1a} Expected data types provided for all inputs. 6 | #' @srrstats {RE4.6} The variance-covariance matrix of the model parameters (via vcov()) 7 | #' 8 | #' @param object Object of class \code{galamm} returned from 9 | #' \code{\link{galamm}}. 10 | #' @param parm The parameters for which the variance-covariance matrix should be 11 | #' calculated. Character vector with one or more of the elements "theta", 12 | #' "beta", "lambda", and "weights". Can also be an integer vector. When given 13 | #' as a character, it must be in only lowercase letters. 14 | #' @param ... Further arguments passed on to other methods. Currently not used. 15 | #' 16 | #' @return A variance-covariance matrix. 17 | #' @export 18 | #' 19 | #' @seealso [confint.galamm()] for the method computing confidence intervals. 20 | #' See [vcov()] for the generic function. 21 | #' 22 | #' @family details of model fit 23 | #' 24 | #' @examples 25 | #' # Linear mixed model with heteroscedastic residuals 26 | #' mod <- galamm( 27 | #' formula = y ~ x + (1 | id), 28 | #' weights = ~ (1 | item), 29 | #' data = hsced 30 | #' ) 31 | #' 32 | #' # Extract covariance matrix for fixed regression coefficients 33 | #' vcov(mod, parm = "beta") 34 | #' 35 | #' # and then for weights, which gives us the variance. 36 | #' vcov(mod, parm = "weights") 37 | #' 38 | vcov.galamm <- function(object, parm = "beta", ...) { 39 | inds <- find_parm_inds(object, parm) 40 | if (length(inds) == 0) { 41 | stop("Parameter not found.") 42 | } 43 | if (object$model$reduced_hessian) { 44 | inds <- inds - max(object$parameters$theta_inds) 45 | } 46 | 47 | if (qr(object$model$hessian)$rank < ncol(object$model$hessian)) { 48 | warning( 49 | "Rank deficient Hessian matrix.", 50 | "Could not compute covariance matrix.\n" 51 | ) 52 | (NA * object$model$hessian)[inds, inds, drop = FALSE] 53 | } else { 54 | -solve(object$model$hessian)[inds, inds, drop = FALSE] 55 | } 56 | } 57 | 58 | 59 | #' Find vector indices corresponding to parameter type 60 | #' 61 | #' @param object An object of class \code{galamm} returned from 62 | #' \code{\link{galamm}}. 63 | #' @param parm Either an integer vector, in which it is simply returned, or 64 | #' a character vector with one or more of the elements \code{"theta"}, 65 | #' \code{"beta"}, \code{"lambda"}, and \code{"weights"}. 66 | #' 67 | #' @srrstats {G1.4a} Internal function documented. 68 | #' 69 | #' @return A numeric vector of indices for the parameters. 70 | #' @noRd 71 | #' 72 | #' @examples 73 | #' mod <- galamm( 74 | #' formula = y ~ x + (1 | id), 75 | #' weights = ~ (1 | item), 76 | #' data = hsced 77 | #' ) 78 | #' 79 | #' # The single Cholesky factor parameter is at the first location 80 | #' find_parm_inds(mod, "theta") 81 | #' 82 | #' # Regression coefficients are at location 2 and 3 83 | #' find_parm_inds(mod, "beta") 84 | #' 85 | #' # Lambda is empty since there are no factor loadings 86 | #' find_parm_inds(mod, "lambda") 87 | #' 88 | #' # Weight index is at location 4 89 | #' find_parm_inds(mod, "weights") 90 | find_parm_inds <- function(object, parm) { 91 | if (is.integer(parm)) { 92 | parm 93 | } else if (is.character(parm)) { 94 | Reduce(function(x, y) { 95 | c(x, eval(parse(text = paste0("object$parameters$", y, "_inds")))) 96 | }, parm, init = integer()) 97 | } else { 98 | stop("parm must be an integer or character vector") 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: https://lcbc-uio.github.io/galamm/ 2 | template: 3 | bootstrap: 5 4 | 5 | articles: 6 | - title: Get started 7 | navbar: ~ 8 | contents: 9 | - galamm 10 | - lmm_factor 11 | - glmm_factor 12 | - lmm_heteroscedastic 13 | - latent_observed_interaction 14 | - mixed_response 15 | - semiparametric 16 | 17 | - title: Advanced topics 18 | navbar: Advanced topics 19 | contents: 20 | - scaling 21 | - optimization 22 | 23 | reference: 24 | - title: Modeling 25 | desc: Fit a generalized additive latent and mixed model. 26 | contents: 27 | - has_concept("modeling functions") 28 | - galamm-package 29 | 30 | - title: High-level model output 31 | desc: Functions for summarising the result of model fits. 32 | contents: 33 | - has_concept("summary functions") 34 | 35 | - title: Model details 36 | desc: Detailed information on specific parts of model fits. 37 | contents: 38 | - has_concept("details of model fit") 39 | 40 | - title: Datasets 41 | desc: Simulated and real example datasets. 42 | contents: 43 | - has_concept("datasets") 44 | 45 | - title: Optimization 46 | desc: Functions to aid in optimization. 47 | contents: 48 | - has_concept("optimization functions") 49 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Submission note 2 | 3 | This is a fix of a WARNING on r-devel-linux-x86_64-fedora-gcc. In addition, some 4 | fixes to summary and print functions. 5 | 6 | I have (1) reproduced the original WARNING and (2) verified that this fix removes it. 7 | 8 | ## Test environments 9 | 10 | * Local Apple M1 Mac, on R4.5.0 11 | * Local gcc15 Ubuntu exactly reproducing r-devel-linux-x86_64-fedora-gcc on which there were warnings. 12 | * R-CMD-check via GitHub Actions on windows-latest, macOS-latest, 13 | ubuntu-20.04 (release), and ubuntu-20.04 (devel). 14 | 15 | ## R CMD check results 16 | 17 | There were 0 ERRORs, 0 WARNINGs, 0 NOTEs 18 | 19 | -------------------------------------------------------------------------------- /data-raw/cognition.R: -------------------------------------------------------------------------------- 1 | library(tidyverse) 2 | library(mgcv) 3 | library(mvtnorm) 4 | set.seed(123) 5 | tps <- 8 6 | tests <- c(3, 2, 4) 7 | family <- c("gaussian", "binomial", "gaussian") 8 | trials <- c(1, 1, 1) 9 | n <- 200 10 | lambda <- list( 11 | c(1, 1.4, .3), 12 | c(1, 2), 13 | c(1, 1, 1, 2) 14 | ) 15 | 16 | # Residual standard deviation for Gaussian model 17 | sdeps1 <- .1 18 | 19 | f0 <- function(x) 2 * sin(pi * x) 20 | f1 <- function(x) exp(2 * x) 21 | f2 <- function(x) { 22 | 0.2 * x^11 * (10 * (1 - x))^6 + 10 * 23 | (10 * x)^3 * (1 - x)^10 24 | } 25 | 26 | funs <- list(f0, f1, f2) 27 | 28 | # Random intercept at the between-timepoint level 29 | covmat3 <- matrix(c( 30 | 1, .3, .4, 31 | .3, 1, .5, 32 | .4, .5, 1 33 | ), ncol = 3) 34 | 35 | zeta3 <- rmvnorm(n, sigma = covmat3) 36 | colnames(zeta3) <- 1:3 37 | 38 | cognition <- crossing( 39 | id = seq_len(n) 40 | ) %>% 41 | bind_cols(zeta3) %>% 42 | pivot_longer(cols = -id, names_to = "domain", values_to = "zeta3") %>% 43 | rowwise() %>% 44 | mutate(x = map(8, ~ sort(runif(.x))), timepoint = list(1:8)) %>% 45 | unnest(cols = c(x, timepoint)) %>% 46 | mutate( 47 | zeta2 = rnorm(nrow(.), sd = .5) 48 | ) %>% 49 | nest_by(domain, .keep = TRUE) %>% 50 | pmap_dfr(function(domain, data) { 51 | data %>% 52 | mutate(linpred = funs[[!!as.integer(domain)]](x) + zeta2 + zeta3) 53 | }) %>% 54 | mutate(tests = tests[as.integer(domain)]) %>% 55 | uncount(tests, .id = "item") %>% 56 | mutate( 57 | loading = map2_dbl( 58 | domain, item, 59 | ~ lambda[[as.integer(.x)]][as.integer(.y)] 60 | ), 61 | trials = map_dbl(domain, ~ trials[[as.integer(.x)]]) 62 | ) %>% 63 | mutate( 64 | y = case_when( 65 | domain == 1 ~ rnorm(nrow(.), mean = loading * linpred, sd = sdeps1), 66 | domain == 2 ~ as.numeric( 67 | rbinom(nrow(.), trials, prob = plogis(loading * linpred)) 68 | ), 69 | domain == 3 ~ rnorm(nrow(.), mean = loading * linpred, sd = sdeps1), 70 | TRUE ~ NA_real_ 71 | ) 72 | ) %>% 73 | select(-zeta3, -zeta2, -linpred, -loading) %>% 74 | mutate( 75 | domain = factor(as.integer(domain)), 76 | item = factor(paste0(as.integer(domain), as.integer(item))), 77 | timepoint = factor(timepoint) 78 | ) %>% 79 | as.data.frame() 80 | 81 | usethis::use_data(cognition, overwrite = TRUE) 82 | -------------------------------------------------------------------------------- /data-raw/diet.R: -------------------------------------------------------------------------------- 1 | library(tidyverse) 2 | diet0 <- read.delim("data-raw/diet.dat", header = TRUE, sep = "\t") 3 | diet0$fiber2[diet0$fiber2 == -99] <- NA_real_ 4 | 5 | diet <- diet0 %>% 6 | pivot_longer( 7 | cols = c(fiber1, fiber2, chd), 8 | values_to = "y", names_to = "item", 9 | values_drop_na = TRUE 10 | ) %>% 11 | mutate( 12 | chd = as.integer(item == "chd"), 13 | fiber = 1L - chd, 14 | fiber2 = as.integer(item == "fiber2"), 15 | item = factor(item, levels = c("fiber1", "fiber2", "chd")) 16 | ) %>% 17 | as.data.frame() 18 | 19 | usethis::use_data(diet, overwrite = TRUE) 20 | -------------------------------------------------------------------------------- /data-raw/epilep.R: -------------------------------------------------------------------------------- 1 | # Download epilepsy data, described at 2 | # http://www.gllamm.org/books/readme.html#11.3 3 | epilep <- read.delim("http://www.gllamm.org/books/epilep.dat", 4 | header = TRUE, 5 | sep = "\t" 6 | ) 7 | 8 | epilep$cons <- NULL 9 | epilep$id <- NULL 10 | epilep$lbas_trt <- NULL 11 | usethis::use_data(epilep, overwrite = TRUE) 12 | -------------------------------------------------------------------------------- /data-raw/hsced.R: -------------------------------------------------------------------------------- 1 | library(tidyverse) 2 | 3 | set.seed(11) 4 | n <- 200 5 | hsced <- tibble( 6 | id = 1:n, 7 | b = rnorm(n) 8 | ) %>% 9 | uncount(3, .id = "tp") %>% 10 | uncount(2, .id = "item") %>% 11 | mutate( 12 | x = runif(nrow(.)), 13 | winv = if_else(item == 1, 1, 2), 14 | y = x + b + rnorm(nrow(.), sd = sqrt(winv)) 15 | ) %>% 16 | select(-b, -winv) %>% 17 | as.data.frame() 18 | 19 | usethis::use_data(hsced, overwrite = TRUE) 20 | 21 | 22 | m1 <- lm(y ~ x, data = hsced, subset = hsced$item == 1) 23 | sigma(m1) 24 | 25 | m2 <- lm(y ~ x, data = hsced, subset = hsced$item == 2) 26 | sigma(m2) 27 | -------------------------------------------------------------------------------- /data-raw/latent_covariates.R: -------------------------------------------------------------------------------- 1 | library(tidyverse) 2 | 3 | n <- 200 4 | 5 | set.seed(1) 6 | latent_covariates <- tibble( 7 | id = seq_len(n), 8 | type = list(c("measurement1", "measurement2", "response")), 9 | x = runif(n) 10 | ) %>% 11 | mutate(eta = rnorm(nrow(.))) %>% 12 | unnest(cols = type) %>% 13 | mutate( 14 | y = case_when( 15 | type == "measurement1" ~ eta, 16 | type == "measurement2" ~ eta * 1.3, 17 | type == "response" ~ .5 * x + eta * (-.3 + .2 * x) 18 | ) + rnorm(nrow(.), sd = .1), 19 | response = as.numeric(type == "response") 20 | ) %>% 21 | select(-eta) %>% 22 | as.data.frame() 23 | 24 | usethis::use_data(latent_covariates, overwrite = TRUE) 25 | 26 | set.seed(3) 27 | latent_covariates_long <- latent_covariates %>% 28 | bind_rows( 29 | filter(latent_covariates, response == 1), 30 | filter(latent_covariates, response == 1), 31 | filter(latent_covariates, response == 1), 32 | filter(latent_covariates, response == 1), 33 | filter(latent_covariates, response == 1) 34 | ) %>% 35 | arrange(id) %>% 36 | mutate( 37 | y = case_when( 38 | response == 1 ~ y + rnorm(nrow(.), sd = .05), 39 | TRUE ~ y 40 | ) 41 | ) 42 | 43 | usethis::use_data(latent_covariates_long, overwrite = TRUE) 44 | -------------------------------------------------------------------------------- /data-raw/mresp.R: -------------------------------------------------------------------------------- 1 | library(dplyr, warn.conflicts = FALSE) 2 | library(tidyr, warn.conflicts = FALSE) 3 | library(purrr, warn.conflicts = FALSE) 4 | 5 | set.seed(100) 6 | mresp <- tibble(id = 1:1000) %>% 7 | mutate(b = rnorm(nrow(.))) %>% 8 | uncount(4, .id = "item") %>% 9 | mutate( 10 | x = runif(nrow(.)), 11 | y = pmap_dbl( 12 | list(b, item, x), ~ if_else(..2 %in% c(1, 2), rnorm(1, ..3 + ..1), 13 | as.numeric(rbinom(1, 1, plogis(..3 + ..1))) 14 | ) 15 | ), 16 | itemgroup = factor(if_else(item %in% c(1, 2), "a", "b")) 17 | ) %>% 18 | select(-b, -item) %>% 19 | as.data.frame() 20 | 21 | usethis::use_data(mresp, overwrite = TRUE) 22 | 23 | set.seed(33) 24 | mresp$grp <- sample(c("a", "b"), size = nrow(mresp), replace = TRUE) 25 | mresp$isgauss <- as.numeric(mresp$itemgroup == "a") 26 | mresp$y <- ifelse(mresp$itemgroup == "a" & mresp$grp == "a", 27 | mresp$y + rnorm(nrow(mresp), sd = 5), mresp$y 28 | ) 29 | 30 | mresp_hsced <- mresp 31 | usethis::use_data(mresp_hsced, overwrite = TRUE) 32 | -------------------------------------------------------------------------------- /data-raw/trajectories.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data-raw/trajectories.rds -------------------------------------------------------------------------------- /data/cognition.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/cognition.rda -------------------------------------------------------------------------------- /data/diet.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/diet.rda -------------------------------------------------------------------------------- /data/epilep.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/epilep.rda -------------------------------------------------------------------------------- /data/hsced.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/hsced.rda -------------------------------------------------------------------------------- /data/latent_covariates.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/latent_covariates.rda -------------------------------------------------------------------------------- /data/latent_covariates_long.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/latent_covariates_long.rda -------------------------------------------------------------------------------- /data/lifespan.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/lifespan.rda -------------------------------------------------------------------------------- /data/mresp.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/mresp.rda -------------------------------------------------------------------------------- /data/mresp_hsced.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/data/mresp_hsced.rda -------------------------------------------------------------------------------- /dev-scripts/create-logo.R: -------------------------------------------------------------------------------- 1 | library(ggplot2) 2 | 3 | library(galamm) 4 | library(hexSticker) 5 | 6 | dat <- subset(cognition, domain == 3 & item == "31") 7 | 8 | p <- ggplot(dat, aes(x = x, y = y, group = id)) + 9 | geom_point(size = .1) + 10 | geom_line(linewidth = .1) + 11 | theme_void() + 12 | theme_transparent() 13 | 14 | sticker(p, 15 | package="galamm", p_size=20, s_x=1, s_y=1.1, s_width=1.7, 16 | s_height = 1.3, p_y = .5, 17 | filename="inst/figures/galamm.png") 18 | -------------------------------------------------------------------------------- /dev-scripts/gamm_factor_structure.R: -------------------------------------------------------------------------------- 1 | 2 | library(tidyverse) 3 | set.seed(123) 4 | gamma <- c(1, 2) 5 | lambda <- c(1, .5, 2, 1, .5, 2) 6 | data <- tibble(id = seq_len(500)) %>% 7 | uncount(2, .id = "domain") %>% 8 | mutate(b = rnorm(nrow(.))) %>% 9 | uncount(3, .id = "item") %>% 10 | mutate(item = factor(paste0(domain, item))) %>% 11 | mutate( 12 | x = runif(nrow(.)), 13 | y = b + gamma[domain] * x * lambda[item] + rnorm(nrow(.), sd = .1), 14 | domain1 = as.numeric(domain == 1), 15 | domain2 = as.numeric(domain == 2) 16 | ) 17 | 18 | lmat <- matrix(c(1, NA, NA, 0, 0, 0, 19 | 0, 0, 0, 1, NA, NA), ncol = 2) 20 | 21 | mod <- galamm( 22 | formula = y ~ 0 + x:domain1:lambda1 + x:domain2:lambda2 + 23 | (0 + domain1:lambda1 + domain2:lambda2 | id), 24 | data = data, 25 | load.var = "item", 26 | lambda = list(lmat), 27 | factor = list(c("lambda1", "lambda2")) 28 | ) 29 | 30 | plot_smooth(mod, scale = 0, pages = 1) 31 | -------------------------------------------------------------------------------- /dev-scripts/latent-interactions.R: -------------------------------------------------------------------------------- 1 | rm(list = ls()) 2 | devtools::load_all() 3 | 4 | load.var <- "type" 5 | lambda <- list(matrix(c(1, NA, NA))) 6 | factor <- list("loading") 7 | factor_interactions <- list(list(~ 1, ~ 1, ~ x)) 8 | 9 | formula <- y ~ s(x, by = response) + (0 + loading | id) + (0 + response | id) 10 | weights <- NULL 11 | data <- latent_covariates_long 12 | family <- gaussian 13 | family_mapping = rep(1L, nrow(data)) 14 | start = NULL 15 | control = galamm_control() 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /dev-scripts/lifespan_demo.R: -------------------------------------------------------------------------------- 1 | library(galamm) 2 | lmat <- matrix(c( 3 | 1, rep(NA, 6), rep(0, 6), 4 | rep(0, 7), 1, NA, rep(0, 4), 5 | rep(0, 9), 1, NA, NA, NA), ncol = 3) 6 | 7 | mod <- galamm( 8 | formula = cbind(y, 16 - y) ~ 0 + retest:domain + test + 9 | sl(age, by = domain, 10 | factor = c("epmem_ability", "wmem_ability", "execfun_ability")) + 11 | (0 + domainepmem:epmem_ability + domainwmem:wmem_ability + 12 | domainexecfun:execfun_ability | id), 13 | data = lifespan, 14 | family = c(binomial, gaussian), 15 | family_mapping = ifelse(lifespan$domain == "execfun", 2, 1), 16 | load.var = "test", 17 | lambda = lmat, 18 | factor = c("epmem_ability", "wmem_ability", "execfun_ability"), 19 | start = list( 20 | theta = mod_init$parameters$parameter_estimates[mod_init$parameters$theta_inds] 21 | ), 22 | control = galamm_control( 23 | optim_control = list(REPORT = 1, trace = 3)) 24 | ) 25 | 26 | summary(mod) 27 | plot_smooth(mod, scale = 0, pages = 1) 28 | -------------------------------------------------------------------------------- /dev-scripts/logo-raw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/dev-scripts/logo-raw.jpg -------------------------------------------------------------------------------- /dev-scripts/multiple_loadings.R: -------------------------------------------------------------------------------- 1 | rm(list=ls()) 2 | devtools::load_all() 3 | 4 | formula = response ~ 0 + item + lat.var:time2 + lat.var:time3 + 5 | lat.var:time4 + (0 + hs:lat.var | hid) + (0 + ms:lat.var | mid) + 6 | (0 + lat.var:time | id) 7 | 8 | 9 | data("KYPSitemsim", package = "PLmixed") 10 | 11 | time.lam <- rbind(c( 1, 0), # Specify time lambda matrix 12 | c(NA, 0), 13 | c(NA, 1), 14 | c(NA, NA)) 15 | 16 | item.lam <- matrix(c(1, NA, NA, NA, NA, NA), ncol = 1) # Specify item lambda matrix 17 | 18 | KYPSitemsim$time2 <- (KYPSitemsim$time == 2) * 1 19 | KYPSitemsim$time3 <- (KYPSitemsim$time == 3) * 1 20 | KYPSitemsim$time4 <- (KYPSitemsim$time == 4) * 1 21 | KYPSitemsim$item <- as.factor(KYPSitemsim$item) 22 | KYPSitemsim$time <- as.factor(KYPSitemsim$time) 23 | 24 | weights <- NULL 25 | data <- KYPSitemsim 26 | family <- gaussian 27 | family_mapping <- rep(1L, nrow(data)) 28 | lambda <- list(time.lam, item.lam) 29 | factor = list(c("ms", "hs"), "lat.var") 30 | load.var = c("time", "item") 31 | factor_interactions <- NULL 32 | start <- NULL 33 | control <- galamm_control() 34 | na.action <- "na.omit" 35 | 36 | # kyps.item.model <- galamm( 37 | # formula = formula, 38 | # data = data, 39 | # lambda = lambda, 40 | # factor = factor, 41 | # load.var = load.var) 42 | # 43 | # 44 | -------------------------------------------------------------------------------- /dev-scripts/predict-mixed-response.R: -------------------------------------------------------------------------------- 1 | rm(list = ls()) 2 | devtools::load_all() 3 | 4 | mod <- galamm( 5 | formula = y ~ x + (0 + loading | id), 6 | data = mresp, 7 | family = c(gaussian, binomial), 8 | family_mapping = ifelse(mresp$itemgroup == "a", 1L, 2L), 9 | load.var = "itemgroup", 10 | lambda = list(matrix(c(1, NA), ncol = 1)), 11 | factor = list("loading") 12 | ) 13 | 14 | predict(mod) 15 | -------------------------------------------------------------------------------- /dev-scripts/predict-newdata.R: -------------------------------------------------------------------------------- 1 | rm(list = ls()) 2 | devtools::load_all() 3 | 4 | object <- galamm( 5 | formula = y ~ lbas * treat + lage + v4 + (1 | subj), 6 | data = epilep, family = poisson 7 | ) 8 | 9 | 10 | newdata <- epilep 11 | type <- "link" 12 | -------------------------------------------------------------------------------- /dev-scripts/predict-semiparametric.R: -------------------------------------------------------------------------------- 1 | rm(list=ls()) 2 | devtools::load_all() 3 | dat <- subset(cognition, domain == 1 & item == "11" & id < 50) 4 | dat$x2 <- rnorm(nrow(dat)) 5 | dat$y <- dat$y + dat$x2 * 10 6 | object <- galamm(formula = y ~ x2 + s(x), data = dat) 7 | 8 | nd <- data.frame(x = runif(100), x2 = runif(100)) 9 | plot(predict(object), predict(object, newdata = dat)) 10 | 11 | predict(object, newdata = nd) 12 | -------------------------------------------------------------------------------- /dev-scripts/testdata-multiple-factors.R: -------------------------------------------------------------------------------- 1 | rm(list=ls()) 2 | devtools::load_all() 3 | 4 | data <- JUDGEsim 5 | data$item <- factor(data$item) 6 | 7 | lambda <- list(rbind( 8 | c(1, 0, 1, 0, 0, 0), 9 | c(NA, 0, NA, 0, 0, 0), 10 | c(NA, 0, NA, 0, 0, 0), 11 | c(0, 1, 0, 1, 0, 0), 12 | c(0, NA, 0, NA, 0, 0), 13 | c(0, NA, 0, NA, 0, 0), 14 | c(0, 0, 0, 0, 1, 0), 15 | c(0, 0, 0, 0, NA, 0), 16 | c(0, 0, 0, 0, NA, 0), 17 | c(0, 0, 0, 0, 0, 1), 18 | c(0, 0, 0, 0, 0, NA), 19 | c(0, 0, 0, 0, 0, NA) 20 | )) 21 | 22 | factor <- list(c( 23 | "teacher1", "teacher2", "trait1.t", 24 | "trait2.t", "trait1.s", "trait2.s" 25 | )) 26 | 27 | formula <- response ~ 0 + item + (0 + teacher1 + teacher2 | tch) + 28 | (0 + trait1.t + trait2.t + trait1.s + trait2.s | stu) + 29 | (1 | class) 30 | 31 | load.var = "item" 32 | 33 | weights = NULL 34 | family = gaussian 35 | family_mapping = rep(1L, nrow(data)) 36 | 37 | factor_interactions = NULL 38 | start = NULL 39 | control = galamm_control() 40 | -------------------------------------------------------------------------------- /galamm.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: 954cd7a2-d830-47c6-9990-720acac3bf64 3 | 4 | RestoreWorkspace: No 5 | SaveWorkspace: No 6 | AlwaysSaveHistory: Default 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: Yes 10 | NumSpacesForTab: 2 11 | Encoding: UTF-8 12 | 13 | RnwWeave: knitr 14 | LaTeX: pdfLaTeX 15 | 16 | AutoAppendNewline: Yes 17 | StripTrailingWhitespace: Yes 18 | LineEndingConversion: Posix 19 | 20 | BuildType: Package 21 | PackageUseDevtools: Yes 22 | PackageInstallArgs: --no-multiarch --with-keep.source 23 | PackageRoxygenize: rd,collate,namespace 24 | -------------------------------------------------------------------------------- /insert_sparse_autodiff.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | library(stringr) 3 | 4 | ff <- read_lines("inst/include/autodiff/common/eigen.hpp") 5 | 6 | ind1 <- str_which(ff, "#include ") 7 | 8 | ff <- c(ff[1:ind1], "#include ", 9 | ff[(ind1 + 1):length(ff)]) 10 | 11 | ind2 <- min(str_which(ff, "EIGEN_VERSION_AT_LEAST")) - 1 12 | 13 | ff <- c(ff[1:ind2], 14 | "template", 15 | "struct VectorTraits>", 16 | "{", 17 | " using ValueType = Scalar;", 18 | " template", 19 | " using ReplaceValueType = Eigen::SparseMatrix;", 20 | "};", 21 | "", 22 | ff[(ind2 + 1):length(ff)]) 23 | 24 | write_lines(ff, "inst/include/autodiff/common/eigen.hpp") 25 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("To cite the 'galamm' package in publications use:") 2 | 3 | bibentry( 4 | bibtype = "Article", 5 | title = "Multilevel Semiparametric Latent Variable Modeling in R with \"galamm\"", 6 | author = person("{\\O}ystein", "S{\\o}rensen"), 7 | journal = "Multivariate Behavioral Research", 8 | year = "2024", 9 | doi = "10.1007/s11336-023-09910-z" 10 | ) 11 | 12 | bibentry( 13 | bibtype = "Article", 14 | title = "Longitudinal Modeling of Age-Dependent Latent Traits with Generalized Additive Latent and Mixed Models", 15 | author = c(person("{\\O}ystein", "S{\\o}rensen"), 16 | person("Kristine B.", "Walhovd"), 17 | person("Anders M.", "Fjell")), 18 | journal = "Psychometrika", 19 | year = "2023", 20 | volume = "88", 21 | number = "2", 22 | pages = "456-486", 23 | doi = "10.1007/s11336-023-09910-z" 24 | ) 25 | -------------------------------------------------------------------------------- /inst/figures/galamm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/inst/figures/galamm.png -------------------------------------------------------------------------------- /inst/include/autodiff/common/numbertraits.hpp: -------------------------------------------------------------------------------- 1 | // _ _ 2 | // _ _|_ _ _|o_|__|_ 3 | // (_||_||_(_)(_|| | | 4 | // 5 | // automatic differentiation made easier in C++ 6 | // https://github.com/autodiff/autodiff 7 | // 8 | // Licensed under the MIT License . 9 | // 10 | // Copyright © 2018–2024 Allan Leal 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #pragma once 31 | 32 | // C++ includes 33 | #include 34 | 35 | namespace autodiff { 36 | namespace detail { 37 | 38 | /// A trait class used to specify whether a type is arithmetic. 39 | template 40 | struct ArithmeticTraits 41 | { 42 | static constexpr bool isArithmetic = std::is_arithmetic_v; 43 | }; 44 | 45 | /// A compile-time constant that indicates whether a type is arithmetic. 46 | template 47 | constexpr bool isArithmetic = ArithmeticTraits>::isArithmetic; 48 | 49 | /// An auxiliary template type to indicate NumberTraits has not been defined for a type. 50 | template 51 | struct NumericTypeInfoNotDefinedFor { using type = T; }; 52 | 53 | /// A trait class used to specify whether a type is an autodiff number. 54 | template 55 | struct NumberTraits 56 | { 57 | /// The underlying floating point type of the autodiff number type. 58 | using NumericType = std::conditional_t, T, NumericTypeInfoNotDefinedFor>; 59 | 60 | /// The order of the autodiff number type. 61 | static constexpr auto Order = 0; 62 | }; 63 | 64 | /// A template alias to get the underlying floating point type of an autodiff number. 65 | template 66 | using NumericType = typename NumberTraits>::NumericType; 67 | 68 | /// A compile-time constant with the order of an autodiff number. 69 | template 70 | constexpr auto Order = NumberTraits>::Order; 71 | 72 | } // namespace detail 73 | } // namespace autodiff 74 | -------------------------------------------------------------------------------- /inst/include/autodiff/common/vectortraits.hpp: -------------------------------------------------------------------------------- 1 | // _ _ 2 | // _ _|_ _ _|o_|__|_ 3 | // (_||_||_(_)(_|| | | 4 | // 5 | // automatic differentiation made easier in C++ 6 | // https://github.com/autodiff/autodiff 7 | // 8 | // Licensed under the MIT License . 9 | // 10 | // Copyright © 2018–2024 Allan Leal 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #pragma once 31 | 32 | // C++ includes 33 | #include 34 | 35 | // autodiff includes 36 | #include 37 | 38 | namespace autodiff { 39 | namespace detail { 40 | 41 | /// An auxiliary template type to indicate VectorTraits has not been defined for a type. 42 | template 43 | struct VectorTraitsNotDefinedFor {}; 44 | 45 | /// An auxiliary template type to indicate VectorTraits::ReplaceValueType is not supported for a type. 46 | template 47 | struct VectorReplaceValueTypeNotSupportedFor {}; 48 | 49 | /// A vector traits to be defined for each autodiff number. 50 | template 51 | struct VectorTraits 52 | { 53 | /// The value type of each entry in the vector. 54 | using ValueType = VectorTraitsNotDefinedFor; 55 | 56 | /// The template alias to replace the value type of a vector type with another value type. 57 | using ReplaceValueType = VectorReplaceValueTypeNotSupportedFor; 58 | }; 59 | 60 | /// A template alias used to get the type of the values in a vector type. 61 | template 62 | using VectorValueType = typename VectorTraits>::ValueType; 63 | 64 | /// A template alias used to get the type of a vector that is equivalent to another but with a different value type. 65 | template 66 | using VectorReplaceValueType = typename VectorTraits>::template ReplaceValueType; 67 | 68 | /// A compile-time constant that indicates with a type is a vector type. 69 | template 70 | constexpr bool isVector = !std::is_same_v>, VectorTraitsNotDefinedFor>>; 71 | 72 | 73 | /// Implementation of VectorTraits for std::vector. 74 | template typename Allocator> 75 | struct VectorTraits>> 76 | { 77 | using ValueType = T; 78 | 79 | template 80 | using ReplaceValueType = std::vector>; 81 | }; 82 | 83 | } // namespace detail 84 | } // namespace autodiff 85 | -------------------------------------------------------------------------------- /inst/include/autodiff/forward/dual.hpp: -------------------------------------------------------------------------------- 1 | // _ _ 2 | // _ _|_ _ _|o_|__|_ 3 | // (_||_||_(_)(_|| | | 4 | // 5 | // automatic differentiation made easier in C++ 6 | // https://github.com/autodiff/autodiff 7 | // 8 | // Licensed under the MIT License . 9 | // 10 | // Copyright © 2018–2024 Allan Leal 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #pragma once 31 | 32 | // autodiff includes 33 | #include 34 | #include 35 | #include 36 | -------------------------------------------------------------------------------- /inst/include/autodiff/forward/real.hpp: -------------------------------------------------------------------------------- 1 | // _ _ 2 | // _ _|_ _ _|o_|__|_ 3 | // (_||_||_(_)(_|| | | 4 | // 5 | // automatic differentiation made easier in C++ 6 | // https://github.com/autodiff/autodiff 7 | // 8 | // Licensed under the MIT License . 9 | // 10 | // Copyright © 2018–2024 Allan Leal 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #pragma once 31 | 32 | // autodiff includes 33 | #include 34 | #include 35 | #include 36 | -------------------------------------------------------------------------------- /inst/include/autodiff/forward/real/eigen.hpp: -------------------------------------------------------------------------------- 1 | // _ _ 2 | // _ _|_ _ _|o_|__|_ 3 | // (_||_||_(_)(_|| | | 4 | // 5 | // automatic differentiation made easier in C++ 6 | // https://github.com/autodiff/autodiff 7 | // 8 | // Licensed under the MIT License . 9 | // 10 | // Copyright © 2018–2024 Allan Leal 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #pragma once 31 | 32 | // Eigen includes 33 | #include 34 | 35 | // autodiff includes 36 | #include 37 | #include 38 | #include 39 | 40 | //------------------------------------------------------------------------------ 41 | // SUPPORT FOR EIGEN MATRICES AND VECTORS OF REAL 42 | //------------------------------------------------------------------------------ 43 | namespace Eigen { 44 | 45 | template 46 | struct NumTraits; 47 | 48 | template 49 | struct NumTraits> : NumTraits // permits to get the epsilon, dummy_precision, lowest, highest functions 50 | { 51 | typedef autodiff::Real Real; 52 | typedef autodiff::Real NonInteger; 53 | typedef autodiff::Real Nested; 54 | enum 55 | { 56 | IsComplex = 0, 57 | IsInteger = 0, 58 | IsSigned = 1, 59 | RequireInitialization = 1, 60 | ReadCost = 1, 61 | AddCost = 3, 62 | MulCost = 3 63 | }; 64 | }; 65 | 66 | template 67 | struct ScalarBinaryOpTraits, T, BinOp> 68 | { 69 | typedef autodiff::Real ReturnType; 70 | }; 71 | 72 | template 73 | struct ScalarBinaryOpTraits, BinOp> 74 | { 75 | typedef autodiff::Real ReturnType; 76 | }; 77 | 78 | } // namespace Eigen 79 | 80 | namespace autodiff { 81 | 82 | AUTODIFF_DEFINE_EIGEN_TYPEDEFS_ALL_SIZES(real0th, real0th); 83 | AUTODIFF_DEFINE_EIGEN_TYPEDEFS_ALL_SIZES(real1st, real1st); 84 | AUTODIFF_DEFINE_EIGEN_TYPEDEFS_ALL_SIZES(real2nd, real2nd); 85 | AUTODIFF_DEFINE_EIGEN_TYPEDEFS_ALL_SIZES(real3rd, real3rd); 86 | AUTODIFF_DEFINE_EIGEN_TYPEDEFS_ALL_SIZES(real4th, real4th); 87 | 88 | AUTODIFF_DEFINE_EIGEN_TYPEDEFS_ALL_SIZES(real, real) 89 | 90 | } // namespace autodiff 91 | -------------------------------------------------------------------------------- /inst/include/autodiff/forward/utils/taylorseries.hpp: -------------------------------------------------------------------------------- 1 | // _ _ 2 | // _ _|_ _ _|o_|__|_ 3 | // (_||_||_(_)(_|| | | 4 | // 5 | // automatic differentiation made easier in C++ 6 | // https://github.com/autodiff/autodiff 7 | // 8 | // Licensed under the MIT License . 9 | // 10 | // Copyright © 2018–2024 Allan Leal 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #pragma once 31 | 32 | // C++ includes 33 | #include 34 | 35 | // autodiff includes 36 | #include 37 | #include 38 | #include 39 | 40 | namespace autodiff { 41 | namespace detail { 42 | 43 | /// Represents a Taylor series along a direction for either a scalar or vector function. 44 | /// @see taylorseries 45 | template 46 | class TaylorSeries 47 | { 48 | public: 49 | /// The numeric floating point type of the derivatives, which can be a vector of values or just one. 50 | using T = std::conditional_t, VectorValueType, V>; 51 | 52 | /// Construct a default TaylorSeries object. 53 | TaylorSeries() = default; 54 | 55 | /// Construct a TaylorSeries object with given directional derivatives. 56 | explicit TaylorSeries(const std::array& derivatives) 57 | : _derivatives(derivatives) 58 | {} 59 | 60 | /// Evaluate the Taylor series object with given directional derivatives. 61 | auto operator()(const T& t) 62 | { 63 | auto res = _derivatives[0]; 64 | auto factor = t; 65 | For<1, N + 1>([&](auto&& i) constexpr { 66 | res += factor * _derivatives[i]; 67 | factor *= t / static_cast(i + 1); 68 | }); 69 | return res; 70 | } 71 | 72 | /// Return the directional derivatives of this TaylorSeries. 73 | auto derivatives() 74 | { 75 | return _derivatives; 76 | } 77 | 78 | private: 79 | /// The directional derivatives of the function up to Nth order. 80 | std::array _derivatives; 81 | }; 82 | 83 | /// Return a TaylorSeries of a scalar or vector function *f* along a direction *v* at *x*. 84 | template 85 | auto taylorseries(const Fun& f, const Along& along, const At& at) 86 | { 87 | auto data = derivatives(f, along, at); 88 | constexpr auto N = data.size() - 1; 89 | using V = typename decltype(data)::value_type; 90 | return TaylorSeries(data); 91 | } 92 | 93 | } // namespace detail 94 | 95 | using detail::taylorseries; 96 | 97 | } // namespace autodiff 98 | -------------------------------------------------------------------------------- /inst/include/autodiff/reverse/var.hpp: -------------------------------------------------------------------------------- 1 | // _ _ 2 | // _ _|_ _ _|o_|__|_ 3 | // (_||_||_(_)(_|| | | 4 | // 5 | // automatic differentiation made easier in C++ 6 | // https://github.com/autodiff/autodiff 7 | // 8 | // Licensed under the MIT License . 9 | // 10 | // Copyright © 2018–2024 Allan Leal 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in all 20 | // copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | // SOFTWARE. 29 | 30 | #pragma once 31 | 32 | // autodiff includes 33 | #include 34 | -------------------------------------------------------------------------------- /inst/testdata/test_multiple_factors.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/inst/testdata/test_multiple_factors.rds -------------------------------------------------------------------------------- /man/VarCorr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/VarCorr.R 3 | \name{VarCorr} 4 | \alias{VarCorr} 5 | \alias{VarCorr.galamm} 6 | \title{Extract variance and correlation components from model} 7 | \usage{ 8 | \method{VarCorr}{galamm}(x, sigma = 1, ...) 9 | } 10 | \arguments{ 11 | \item{x}{An object of class \code{galamm} returned from \code{\link{galamm}}.} 12 | 13 | \item{sigma}{Numeric value used to multiply the standard deviations. Defaults 14 | to 1.} 15 | 16 | \item{...}{Other arguments passed onto other methods. Currently not used.} 17 | } 18 | \value{ 19 | An object of class \code{c("VarCorr.galamm", "VarCorr.merMod")}. 20 | } 21 | \description{ 22 | Extract variance and correlation components from model 23 | } 24 | \examples{ 25 | # Linear mixed model with heteroscedastic residuals 26 | mod <- galamm( 27 | formula = y ~ x + (1 | id), 28 | weights = ~ (1 | item), 29 | data = hsced 30 | ) 31 | 32 | # Extract information on variance and covariance 33 | VarCorr(mod) 34 | 35 | # Convert to data frame 36 | # (this invokes lme4's function as.data.frame.VarCorr.merMod) 37 | as.data.frame(VarCorr(mod)) 38 | 39 | } 40 | \seealso{ 41 | \code{\link[=print.VarCorr.galamm]{print.VarCorr.galamm()}} for the print function. 42 | 43 | Other details of model fit: 44 | \code{\link{coef.galamm}()}, 45 | \code{\link{confint.galamm}()}, 46 | \code{\link{deviance.galamm}()}, 47 | \code{\link{factor_loadings.galamm}()}, 48 | \code{\link{family.galamm}()}, 49 | \code{\link{fitted.galamm}()}, 50 | \code{\link{fixef}()}, 51 | \code{\link{formula.galamm}()}, 52 | \code{\link{llikAIC}()}, 53 | \code{\link{logLik.galamm}()}, 54 | \code{\link{nobs.galamm}()}, 55 | \code{\link{predict.galamm}()}, 56 | \code{\link{print.VarCorr.galamm}()}, 57 | \code{\link{ranef.galamm}()}, 58 | \code{\link{residuals.galamm}()}, 59 | \code{\link{response}()}, 60 | \code{\link{sigma.galamm}()}, 61 | \code{\link{vcov.galamm}()} 62 | } 63 | \concept{details of model fit} 64 | -------------------------------------------------------------------------------- /man/anova.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/anova.galamm.R 3 | \name{anova.galamm} 4 | \alias{anova.galamm} 5 | \title{Compare likelihoods of galamm objects} 6 | \usage{ 7 | \method{anova}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{...}{Other fitted models of class \code{galamm}. Currently, if no 14 | models are provided in this argument, no table will be returned.} 15 | } 16 | \value{ 17 | A table with model comparison metric. 18 | } 19 | \description{ 20 | Anova function for comparing different GALAMMs fitted on the 21 | same data. 22 | } 23 | \examples{ 24 | # Poisson GLMM 25 | count_mod <- galamm( 26 | formula = y ~ lbas * treat + lage + v4 + (1 | subj), 27 | data = epilep, family = poisson 28 | ) 29 | 30 | # Model without interaction 31 | count_mod0 <- galamm( 32 | formula = y ~ lbas + treat + lage + v4 + (1 | subj), 33 | data = epilep, family = poisson 34 | ) 35 | 36 | # Model comparison 37 | anova(count_mod, count_mod0) 38 | 39 | } 40 | \references{ 41 | \insertRef{batesFittingLinearMixedEffects2015}{galamm} 42 | } 43 | \seealso{ 44 | \code{\link[=summary.galamm]{summary.galamm()}} for the summary method and \code{\link[=anova]{anova()}} for the 45 | generic function. 46 | 47 | Other summary functions: 48 | \code{\link{plot.galamm}()}, 49 | \code{\link{plot_smooth.galamm}()}, 50 | \code{\link{print.galamm}()}, 51 | \code{\link{print.summary.galamm}()}, 52 | \code{\link{summary.galamm}()} 53 | } 54 | \author{ 55 | Some of the source code for this function is adapted from 56 | \code{lme4:::anova.merMod}, with authors Douglas M. Bates, Martin Maechler, 57 | Ben Bolker, and Steve Walker. 58 | } 59 | \concept{summary functions} 60 | -------------------------------------------------------------------------------- /man/coef.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/coef.R 3 | \name{coef.galamm} 4 | \alias{coef.galamm} 5 | \title{Extract galamm coefficients} 6 | \usage{ 7 | \method{coef}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm}, from \code{\link{galamm}}.} 11 | 12 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 13 | } 14 | \value{ 15 | A matrix with the requested coefficients. 16 | } 17 | \description{ 18 | Currently, this function only returns the fixed effects. 19 | } 20 | \examples{ 21 | # Poisson GLMM 22 | count_mod <- galamm( 23 | formula = y ~ lbas * treat + lage + v4 + (1 | subj), 24 | data = epilep, family = poisson 25 | ) 26 | 27 | # Extract coefficients 28 | coef(count_mod) 29 | 30 | } 31 | \seealso{ 32 | \code{\link[=fixef.galamm]{fixef.galamm()}} for fixed effects, \code{\link[=ranef.galamm]{ranef.galamm()}} for random 33 | effects, and \code{\link[=coef]{coef()}} for the generic function. 34 | 35 | Other details of model fit: 36 | \code{\link{VarCorr}()}, 37 | \code{\link{confint.galamm}()}, 38 | \code{\link{deviance.galamm}()}, 39 | \code{\link{factor_loadings.galamm}()}, 40 | \code{\link{family.galamm}()}, 41 | \code{\link{fitted.galamm}()}, 42 | \code{\link{fixef}()}, 43 | \code{\link{formula.galamm}()}, 44 | \code{\link{llikAIC}()}, 45 | \code{\link{logLik.galamm}()}, 46 | \code{\link{nobs.galamm}()}, 47 | \code{\link{predict.galamm}()}, 48 | \code{\link{print.VarCorr.galamm}()}, 49 | \code{\link{ranef.galamm}()}, 50 | \code{\link{residuals.galamm}()}, 51 | \code{\link{response}()}, 52 | \code{\link{sigma.galamm}()}, 53 | \code{\link{vcov.galamm}()} 54 | } 55 | \concept{details of model fit} 56 | -------------------------------------------------------------------------------- /man/cognition.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{cognition} 5 | \alias{cognition} 6 | \title{Simulated Data with Measurements of Cognitive Abilities} 7 | \format{ 8 | \subsection{\code{cognition} A data frame with 14400 rows and 7 columns:}{ 9 | 10 | \describe{ 11 | \item{id}{Subject ID.} 12 | \item{domain}{Factor variable denoting the cognitive domain.} 13 | \item{x}{Explanatory variable.} 14 | \item{timepoint}{Factor variable denoting the timepoint.} 15 | \item{item}{Factor variable denoting the item within the tests of each 16 | cognitive domain.} 17 | \item{trials}{Number of trials, if applicable.} 18 | \item{y}{Response variable. For domain 1 a real number, for domain 2 a 19 | binomially distributed variable based on a single trial, for 20 | domain 3 a real number.} 21 | } 22 | } 23 | } 24 | \usage{ 25 | cognition 26 | } 27 | \description{ 28 | Simulated dataset mimicking the measurement of abilities in three cognitive 29 | domains. The latent traits (cognitive ability in a given domain) are based on 30 | the functions in \code{mgcv::gamSim} 31 | \insertCite{woodGeneralizedAdditiveModels2017}{galamm}, and depend on the 32 | explanatory variable x. 33 | } 34 | \references{ 35 | \insertAllCited{} 36 | } 37 | \seealso{ 38 | Other datasets: 39 | \code{\link{diet}}, 40 | \code{\link{epilep}}, 41 | \code{\link{hsced}}, 42 | \code{\link{latent_covariates}}, 43 | \code{\link{latent_covariates_long}}, 44 | \code{\link{lifespan}}, 45 | \code{\link{mresp}}, 46 | \code{\link{mresp_hsced}} 47 | } 48 | \concept{datasets} 49 | \keyword{datasets} 50 | -------------------------------------------------------------------------------- /man/confint.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/confint.R 3 | \name{confint.galamm} 4 | \alias{confint.galamm} 5 | \title{Confidence intervals for model parameters} 6 | \usage{ 7 | \method{confint}{galamm}(object, parm, level = 0.95, method = "Wald", ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{parm}{Parameters for which to compute intervals. Use \code{"theta"} to 14 | get all variance parameters, \code{"beta"} to get all fixed regression 15 | coefficients, \code{"lambda"} to get all factor loadings, and 16 | \code{"weights"} to get all weights. The parameter can also be given as a 17 | numeric vector with indices specifying the parameters. When given as 18 | characters, the arguments are case sensitive.} 19 | 20 | \item{level}{Decimal number specifying the confidence level. Defaults to 0.95.} 21 | 22 | \item{method}{Character of length one specifying the type of confidence 23 | interval. Currently only "Wald" is available. The argument is case 24 | sensitive.} 25 | 26 | \item{...}{Other arguments passed on to other methods. Currently not used.} 27 | } 28 | \value{ 29 | A matrix with the requested confidence intervals. 30 | } 31 | \description{ 32 | Confidence intervals for model parameters 33 | } 34 | \examples{ 35 | # Poisson GLMM 36 | count_mod <- galamm( 37 | formula = y ~ lbas * treat + lage + v4 + (1 | subj), 38 | data = epilep, family = poisson 39 | ) 40 | 41 | confint(count_mod, parm = "beta", level = .99) 42 | 43 | } 44 | \seealso{ 45 | \code{\link[=fixef.galamm]{fixef.galamm()}} for fixed effects, \code{\link[=coef.galamm]{coef.galamm()}} for coefficients 46 | more generally, and \code{\link[=vcov.galamm]{vcov.galamm()}} for the variance-covariance matrix. 47 | \code{\link[=confint]{confint()}} is the generic function. 48 | 49 | Other details of model fit: 50 | \code{\link{VarCorr}()}, 51 | \code{\link{coef.galamm}()}, 52 | \code{\link{deviance.galamm}()}, 53 | \code{\link{factor_loadings.galamm}()}, 54 | \code{\link{family.galamm}()}, 55 | \code{\link{fitted.galamm}()}, 56 | \code{\link{fixef}()}, 57 | \code{\link{formula.galamm}()}, 58 | \code{\link{llikAIC}()}, 59 | \code{\link{logLik.galamm}()}, 60 | \code{\link{nobs.galamm}()}, 61 | \code{\link{predict.galamm}()}, 62 | \code{\link{print.VarCorr.galamm}()}, 63 | \code{\link{ranef.galamm}()}, 64 | \code{\link{residuals.galamm}()}, 65 | \code{\link{response}()}, 66 | \code{\link{sigma.galamm}()}, 67 | \code{\link{vcov.galamm}()} 68 | } 69 | \concept{details of model fit} 70 | -------------------------------------------------------------------------------- /man/deviance.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/logLik.galamm.R 3 | \name{deviance.galamm} 4 | \alias{deviance.galamm} 5 | \title{Extract deviance of galamm object} 6 | \usage{ 7 | \method{deviance}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{Object of class \code{galamm}, returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{...}{Other arguments passed on to other methods. Currently not used.} 14 | } 15 | \value{ 16 | A numeric value giving the deviance of the model fit. 17 | } 18 | \description{ 19 | Extract deviance of galamm object 20 | } 21 | \examples{ 22 | # Linear mixed model with heteroscedastic residuals 23 | mod <- galamm( 24 | formula = y ~ x + (1 | id), 25 | weights = ~ (1 | item), 26 | data = hsced 27 | ) 28 | 29 | # Extract deviance 30 | deviance(mod) 31 | 32 | } 33 | \seealso{ 34 | \code{\link[=logLik.galamm]{logLik.galamm()}} for a function returning the log likelihood and 35 | \code{\link[=deviance]{deviance()}} for the generic function. 36 | 37 | Other details of model fit: 38 | \code{\link{VarCorr}()}, 39 | \code{\link{coef.galamm}()}, 40 | \code{\link{confint.galamm}()}, 41 | \code{\link{factor_loadings.galamm}()}, 42 | \code{\link{family.galamm}()}, 43 | \code{\link{fitted.galamm}()}, 44 | \code{\link{fixef}()}, 45 | \code{\link{formula.galamm}()}, 46 | \code{\link{llikAIC}()}, 47 | \code{\link{logLik.galamm}()}, 48 | \code{\link{nobs.galamm}()}, 49 | \code{\link{predict.galamm}()}, 50 | \code{\link{print.VarCorr.galamm}()}, 51 | \code{\link{ranef.galamm}()}, 52 | \code{\link{residuals.galamm}()}, 53 | \code{\link{response}()}, 54 | \code{\link{sigma.galamm}()}, 55 | \code{\link{vcov.galamm}()} 56 | } 57 | \concept{details of model fit} 58 | -------------------------------------------------------------------------------- /man/diet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{diet} 5 | \alias{diet} 6 | \title{Diet Data} 7 | \format{ 8 | \subsection{\code{diet} A data frame with 236 rows and 7 columns:}{ 9 | 10 | \describe{ 11 | \item{id}{Subject ID.} 12 | \item{age}{Age (standardized).} 13 | \item{bus}{Dummy variable indicating whether the subject is a bus 14 | driver or banking staff.} 15 | \item{item}{Integer indicating whether the outcome is fiber intake at 16 | time 1 (item = 1), fiber intake at time 2 (item = 2), or coronary heart 17 | disease (item = 3).} 18 | \item{y}{Outcome.} 19 | \item{chd}{Dummy variable indicating whether y is an indicator for 20 | coronary heart disease, coded as 0/1.} 21 | \item{fiber}{Dummy variable indicating whether y is a fiber measurement 22 | at either timepoint 1 or 2.} 23 | \item{fiber2}{Dummy variable indicating whether y is a fiber measurement 24 | at timepoint 2.} 25 | } 26 | } 27 | } 28 | \source{ 29 | \url{http://www.gllamm.org/books/readme.html#14.2} 30 | } 31 | \usage{ 32 | diet 33 | } 34 | \description{ 35 | Longitudinal epilepsy data from 36 | \insertCite{morrisDietHeartPostscript1977;textual}{galamm}. This 37 | documentation is based on Chapter 14.2 of 38 | \insertCite{skrondalGeneralizedLatentVariable2004;textual}{galamm}, where the 39 | dataset is used. See also 40 | \insertCite{rabe-heskethCorrectingCovariateMeasurement2003;textual}{galamm}. 41 | } 42 | \references{ 43 | \insertAllCited{} 44 | } 45 | \seealso{ 46 | Other datasets: 47 | \code{\link{cognition}}, 48 | \code{\link{epilep}}, 49 | \code{\link{hsced}}, 50 | \code{\link{latent_covariates}}, 51 | \code{\link{latent_covariates_long}}, 52 | \code{\link{lifespan}}, 53 | \code{\link{mresp}}, 54 | \code{\link{mresp_hsced}} 55 | } 56 | \concept{datasets} 57 | \keyword{datasets} 58 | -------------------------------------------------------------------------------- /man/epilep.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{epilep} 5 | \alias{epilep} 6 | \title{Epilepsy Data} 7 | \format{ 8 | \subsection{\code{epilep} A data frame with 236 rows and 7 columns:}{ 9 | 10 | \describe{ 11 | \item{subj}{Subject ID.} 12 | \item{y}{Number of seizures.} 13 | \item{treat}{Dummy variable for treatment group.} 14 | \item{visit}{Time at visit.} 15 | \item{v4}{Dummy for visit 4.} 16 | \item{lage}{Logarithm of age.} 17 | \item{lbas}{Logarithm of a quarter of the number of seizures in the eight 18 | weeks preceding entry into the trial.} 19 | } 20 | } 21 | } 22 | \source{ 23 | \url{http://www.gllamm.org/books/readme.html#11.3} 24 | } 25 | \usage{ 26 | epilep 27 | } 28 | \description{ 29 | Longitudinal epilepsy data from 30 | \insertCite{leppikControlledStudyProgabide1987;textual}{galamm}. This 31 | documentation is based on Chapter 11.3 of 32 | \insertCite{skrondalGeneralizedLatentVariable2004;textual}{galamm}, where 33 | the dataset is used. 34 | } 35 | \references{ 36 | \insertAllCited{} 37 | } 38 | \seealso{ 39 | Other datasets: 40 | \code{\link{cognition}}, 41 | \code{\link{diet}}, 42 | \code{\link{hsced}}, 43 | \code{\link{latent_covariates}}, 44 | \code{\link{latent_covariates_long}}, 45 | \code{\link{lifespan}}, 46 | \code{\link{mresp}}, 47 | \code{\link{mresp_hsced}} 48 | } 49 | \concept{datasets} 50 | \keyword{datasets} 51 | -------------------------------------------------------------------------------- /man/extract_optim_parameters.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/extract_optim_parameters.R 3 | \name{extract_optim_parameters.galamm} 4 | \alias{extract_optim_parameters.galamm} 5 | \alias{extract_optim_parameters} 6 | \title{Extract parameters from fitted model for use as initial values} 7 | \usage{ 8 | \method{extract_optim_parameters}{galamm}(object) 9 | } 10 | \arguments{ 11 | \item{object}{Object of class \code{galamm} returned from 12 | \code{\link{galamm}}.} 13 | } 14 | \value{ 15 | A \code{list} object containing the following elements: 16 | \itemize{ 17 | \item \code{theta} Numerical vector of variance components, i.e., entries of 18 | the lower Cholesky form of the covariance matrix of random effects. 19 | \item \code{beta} Fixed regression coefficients. 20 | \item \code{lambda} Factor loadings. 21 | \item \code{weights} Weights for heteroscedastic residuals. 22 | } 23 | } 24 | \description{ 25 | This function extracts parameter values from a fitted model object in a form 26 | that can be directly provided as initial values for a new model fit. 27 | } 28 | \examples{ 29 | # Fit linear mixed model with heteroscedastic residuals 30 | mod <- galamm( 31 | formula = y ~ x + (1 | id), 32 | weights = ~ (1 | item), 33 | data = hsced 34 | ) 35 | 36 | # Extract parameters 37 | start <- extract_optim_parameters(mod) 38 | 39 | # Fit again using the Nelder-Mead algorithm, using start as initial values: 40 | mod_nm <- galamm( 41 | formula = y ~ x + (1 | id), 42 | weights = ~ (1 | item), 43 | data = hsced, 44 | start = start, 45 | control = galamm_control(method = "Nelder-Mead") 46 | ) 47 | 48 | } 49 | \seealso{ 50 | Other optimization functions: 51 | \code{\link{galamm_control}()} 52 | } 53 | \concept{optimization functions} 54 | -------------------------------------------------------------------------------- /man/factor_loadings.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/factor_loadings.R 3 | \name{factor_loadings.galamm} 4 | \alias{factor_loadings.galamm} 5 | \alias{factor_loadings} 6 | \title{Extract factor loadings from galamm object} 7 | \usage{ 8 | \method{factor_loadings}{galamm}(object) 9 | } 10 | \arguments{ 11 | \item{object}{Object of class \code{galamm} returned from 12 | \code{\link{galamm}}.} 13 | } 14 | \value{ 15 | A matrix containing the estimated factor loadings with corresponding 16 | standard deviations. 17 | } 18 | \description{ 19 | Extract factor loadings from galamm object 20 | } 21 | \details{ 22 | This function has been named \code{factor_loadings} rather than just 23 | \code{loadings} to avoid conflict with \code{stats::loadings}. 24 | } 25 | \examples{ 26 | # Logistic mixed model with factor loadings, example from PLmixed 27 | data("IRTsim", package = "PLmixed") 28 | 29 | # Reduce data size for the example to run faster 30 | IRTsub <- IRTsim[IRTsim$item < 4, ] 31 | IRTsub <- IRTsub[sample(nrow(IRTsub), 300), ] 32 | IRTsub$item <- factor(IRTsub$item) 33 | 34 | # Fix loading for first item to 1, and estimate the two others freely 35 | loading_matrix <- matrix(c(1, NA, NA), ncol = 1) 36 | 37 | # Estimate model 38 | mod <- galamm(y ~ item + (0 + ability | sid) + (0 + ability | school), 39 | data = IRTsub, family = binomial, load.var = "item", 40 | factor = "ability", lambda = loading_matrix 41 | ) 42 | 43 | # Show estimated factor loadings, with standard errors 44 | factor_loadings(mod) 45 | 46 | } 47 | \seealso{ 48 | \code{\link[=fixef.galamm]{fixef.galamm()}} for fixed regression coefficients, 49 | \code{\link[=confint.galamm]{confint.galamm()}} for confidence intervals, and \code{\link[=coef.galamm]{coef.galamm()}} for 50 | coefficients more generally. 51 | 52 | Other details of model fit: 53 | \code{\link{VarCorr}()}, 54 | \code{\link{coef.galamm}()}, 55 | \code{\link{confint.galamm}()}, 56 | \code{\link{deviance.galamm}()}, 57 | \code{\link{family.galamm}()}, 58 | \code{\link{fitted.galamm}()}, 59 | \code{\link{fixef}()}, 60 | \code{\link{formula.galamm}()}, 61 | \code{\link{llikAIC}()}, 62 | \code{\link{logLik.galamm}()}, 63 | \code{\link{nobs.galamm}()}, 64 | \code{\link{predict.galamm}()}, 65 | \code{\link{print.VarCorr.galamm}()}, 66 | \code{\link{ranef.galamm}()}, 67 | \code{\link{residuals.galamm}()}, 68 | \code{\link{response}()}, 69 | \code{\link{sigma.galamm}()}, 70 | \code{\link{vcov.galamm}()} 71 | } 72 | \author{ 73 | The example for this function comes from \code{PLmixed}, with authors 74 | Nicholas Rockwood and Minjeong Jeon 75 | \insertCite{rockwoodEstimatingComplexMeasurement2019}{galamm}. 76 | } 77 | \concept{details of model fit} 78 | -------------------------------------------------------------------------------- /man/family.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/family.R 3 | \name{family.galamm} 4 | \alias{family.galamm} 5 | \title{Extract family or families from fitted galamm} 6 | \usage{ 7 | \method{family}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 14 | } 15 | \value{ 16 | A list of family objects. 17 | } 18 | \description{ 19 | This function returns a list of families for an object of class 20 | \code{galamm}, returned from \code{\link{galamm}}. 21 | } 22 | \examples{ 23 | # Mixed response model 24 | loading_matrix <- matrix(c(1, NA), ncol = 1) 25 | families <- c(gaussian, binomial) 26 | family_mapping <- ifelse(mresp$itemgroup == "a", 1, 2) 27 | 28 | mixed_resp <- galamm( 29 | formula = y ~ x + (0 + level | id), 30 | data = mresp, 31 | family = families, 32 | family_mapping = family_mapping, 33 | load.var = "itemgroup", 34 | lambda = loading_matrix, 35 | factor = "level" 36 | ) 37 | 38 | # This model has two family objects 39 | family(mixed_resp) 40 | 41 | } 42 | \seealso{ 43 | \code{\link[=galamm]{galamm()}} 44 | 45 | Other details of model fit: 46 | \code{\link{VarCorr}()}, 47 | \code{\link{coef.galamm}()}, 48 | \code{\link{confint.galamm}()}, 49 | \code{\link{deviance.galamm}()}, 50 | \code{\link{factor_loadings.galamm}()}, 51 | \code{\link{fitted.galamm}()}, 52 | \code{\link{fixef}()}, 53 | \code{\link{formula.galamm}()}, 54 | \code{\link{llikAIC}()}, 55 | \code{\link{logLik.galamm}()}, 56 | \code{\link{nobs.galamm}()}, 57 | \code{\link{predict.galamm}()}, 58 | \code{\link{print.VarCorr.galamm}()}, 59 | \code{\link{ranef.galamm}()}, 60 | \code{\link{residuals.galamm}()}, 61 | \code{\link{response}()}, 62 | \code{\link{sigma.galamm}()}, 63 | \code{\link{vcov.galamm}()} 64 | } 65 | \concept{details of model fit} 66 | -------------------------------------------------------------------------------- /man/figures/README-pressure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/man/figures/README-pressure-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/man/figures/README-unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/man/figures/README-unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/man/figures/logo.png -------------------------------------------------------------------------------- /man/fitted.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fitted.galamm.R 3 | \name{fitted.galamm} 4 | \alias{fitted.galamm} 5 | \title{Extract model fitted values} 6 | \usage{ 7 | \method{fitted}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 14 | } 15 | \value{ 16 | A numerical vector with fit values for each row in the input data. 17 | } 18 | \description{ 19 | Extracts fitted values from a model including random effects. 20 | } 21 | \examples{ 22 | # Linear mixed model with heteroscedastic residuals 23 | mod <- galamm( 24 | formula = y ~ x + (1 | id), 25 | weights = ~ (1 | item), 26 | data = hsced 27 | ) 28 | 29 | # Extract fitted values and plot against x 30 | plot(hsced$x, fitted(mod)) 31 | 32 | } 33 | \seealso{ 34 | Other details of model fit: 35 | \code{\link{VarCorr}()}, 36 | \code{\link{coef.galamm}()}, 37 | \code{\link{confint.galamm}()}, 38 | \code{\link{deviance.galamm}()}, 39 | \code{\link{factor_loadings.galamm}()}, 40 | \code{\link{family.galamm}()}, 41 | \code{\link{fixef}()}, 42 | \code{\link{formula.galamm}()}, 43 | \code{\link{llikAIC}()}, 44 | \code{\link{logLik.galamm}()}, 45 | \code{\link{nobs.galamm}()}, 46 | \code{\link{predict.galamm}()}, 47 | \code{\link{print.VarCorr.galamm}()}, 48 | \code{\link{ranef.galamm}()}, 49 | \code{\link{residuals.galamm}()}, 50 | \code{\link{response}()}, 51 | \code{\link{sigma.galamm}()}, 52 | \code{\link{vcov.galamm}()} 53 | } 54 | \concept{details of model fit} 55 | -------------------------------------------------------------------------------- /man/fixef.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fixef.R 3 | \name{fixef} 4 | \alias{fixef} 5 | \alias{fixef.galamm} 6 | \title{Extract fixed effects from galamm objects} 7 | \usage{ 8 | \method{fixef}{galamm}(object, ...) 9 | } 10 | \arguments{ 11 | \item{object}{An object of class \code{galamm}, returned from 12 | \code{\link{galamm}}.} 13 | 14 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 15 | } 16 | \value{ 17 | A named \code{numeric} vector containing the requested fixed effects. 18 | } 19 | \description{ 20 | Extract the fixed regression coefficients. 21 | } 22 | \examples{ 23 | # Poisson GLMM 24 | count_mod <- galamm( 25 | formula = y ~ lbas * treat + lage + v4 + (1 | subj), 26 | data = epilep, family = poisson 27 | ) 28 | 29 | # Extract fixed effects 30 | fixef(count_mod) 31 | 32 | } 33 | \seealso{ 34 | \code{\link[=ranef.galamm]{ranef.galamm()}} for random effects, \code{\link[=coef.galamm]{coef.galamm()}} for 35 | coefficients more generally, and \code{\link[=confint.galamm]{confint.galamm()}} for confidence intervals. 36 | 37 | Other details of model fit: 38 | \code{\link{VarCorr}()}, 39 | \code{\link{coef.galamm}()}, 40 | \code{\link{confint.galamm}()}, 41 | \code{\link{deviance.galamm}()}, 42 | \code{\link{factor_loadings.galamm}()}, 43 | \code{\link{family.galamm}()}, 44 | \code{\link{fitted.galamm}()}, 45 | \code{\link{formula.galamm}()}, 46 | \code{\link{llikAIC}()}, 47 | \code{\link{logLik.galamm}()}, 48 | \code{\link{nobs.galamm}()}, 49 | \code{\link{predict.galamm}()}, 50 | \code{\link{print.VarCorr.galamm}()}, 51 | \code{\link{ranef.galamm}()}, 52 | \code{\link{residuals.galamm}()}, 53 | \code{\link{response}()}, 54 | \code{\link{sigma.galamm}()}, 55 | \code{\link{vcov.galamm}()} 56 | } 57 | \concept{details of model fit} 58 | -------------------------------------------------------------------------------- /man/formula.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/formula.R 3 | \name{formula.galamm} 4 | \alias{formula.galamm} 5 | \title{Extract formula from fitted galamm object} 6 | \usage{ 7 | \method{formula}{galamm}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{Object of class \code{galamm} returned from \code{\link{galamm}}.} 11 | 12 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 13 | } 14 | \value{ 15 | The formula used to fit the model. 16 | } 17 | \description{ 18 | Extract formula from fitted galamm object 19 | } 20 | \examples{ 21 | # Mixed response model ------------------------------------------------------ 22 | 23 | # The mresp dataset contains a mix of binomial and Gaussian responses. 24 | 25 | # We need to estimate a factor loading which scales the two response types. 26 | loading_matrix <- matrix(c(1, NA), ncol = 1) 27 | 28 | # Define mapping to families. 29 | families <- c(gaussian, binomial) 30 | family_mapping <- ifelse(mresp$itemgroup == "a", 1, 2) 31 | 32 | 33 | # Fit the model 34 | mod <- galamm( 35 | formula = y ~ x + (0 + level | id), 36 | data = mresp, 37 | family = families, 38 | family_mapping = family_mapping, 39 | factor = "level", 40 | load.var = "itemgroup", 41 | lambda = loading_matrix 42 | ) 43 | 44 | # Formula 45 | formula(mod) 46 | 47 | } 48 | \seealso{ 49 | Other details of model fit: 50 | \code{\link{VarCorr}()}, 51 | \code{\link{coef.galamm}()}, 52 | \code{\link{confint.galamm}()}, 53 | \code{\link{deviance.galamm}()}, 54 | \code{\link{factor_loadings.galamm}()}, 55 | \code{\link{family.galamm}()}, 56 | \code{\link{fitted.galamm}()}, 57 | \code{\link{fixef}()}, 58 | \code{\link{llikAIC}()}, 59 | \code{\link{logLik.galamm}()}, 60 | \code{\link{nobs.galamm}()}, 61 | \code{\link{predict.galamm}()}, 62 | \code{\link{print.VarCorr.galamm}()}, 63 | \code{\link{ranef.galamm}()}, 64 | \code{\link{residuals.galamm}()}, 65 | \code{\link{response}()}, 66 | \code{\link{sigma.galamm}()}, 67 | \code{\link{vcov.galamm}()} 68 | } 69 | \concept{details of model fit} 70 | -------------------------------------------------------------------------------- /man/galamm-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/galamm-package.R 3 | \docType{package} 4 | \name{galamm-package} 5 | \alias{galamm-package} 6 | \title{galamm: Generalized Additive Latent and Mixed Models} 7 | \description{ 8 | \if{html}{\figure{logo.png}{options: style='float: right' alt='logo' width='120'}} 9 | 10 | Estimates generalized additive latent and mixed models using maximum marginal likelihood, as defined in Sorensen et al. (2023) \doi{10.1007/s11336-023-09910-z}, which is an extension of Rabe-Hesketh and Skrondal (2004)'s unifying framework for multilevel latent variable modeling \doi{10.1007/BF02295939}. Efficient computation is done using sparse matrix methods, Laplace approximation, and automatic differentiation. The framework includes generalized multilevel models with heteroscedastic residuals, mixed response types, factor loadings, smoothing splines, crossed random effects, and combinations thereof. Syntax for model formulation is close to 'lme4' (Bates et al. (2015) \doi{10.18637/jss.v067.i01}) and 'PLmixed' (Rockwood and Jeon (2019) \doi{10.1080/00273171.2018.1516541}). 11 | } 12 | \references{ 13 | \insertRef{sorensenLongitudinalModelingAgeDependent2023}{galamm} 14 | } 15 | \seealso{ 16 | Useful links: 17 | \itemize{ 18 | \item \url{https://github.com/LCBC-UiO/galamm} 19 | \item \url{https://lcbc-uio.github.io/galamm/} 20 | \item Report bugs at \url{https://github.com/LCBC-UiO/galamm/issues} 21 | } 22 | 23 | } 24 | \author{ 25 | \strong{Maintainer}: Øystein Sørensen \email{oystein.sorensen@psykologi.uio.no} (\href{https://orcid.org/0000-0003-0724-3542}{ORCID}) 26 | 27 | Other contributors: 28 | \itemize{ 29 | \item Douglas Bates [contributor] 30 | \item Ben Bolker [contributor] 31 | \item Martin Maechler [contributor] 32 | \item Allan Leal [contributor] 33 | \item Fabian Scheipl [contributor] 34 | \item Steven Walker [contributor] 35 | \item Simon Wood [contributor] 36 | } 37 | 38 | } 39 | \keyword{internal} 40 | -------------------------------------------------------------------------------- /man/galamm_control.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/galamm_control.R 3 | \name{galamm_control} 4 | \alias{galamm_control} 5 | \title{Control values for galamm fit} 6 | \usage{ 7 | galamm_control( 8 | optim_control = list(), 9 | method = c("L-BFGS-B", "Nelder-Mead"), 10 | maxit_conditional_modes = 10, 11 | pirls_tol_abs = 0.01, 12 | reduced_hessian = FALSE 13 | ) 14 | } 15 | \arguments{ 16 | \item{optim_control}{List containing optimization parameters. If \code{method 17 | = "L-BFGS-B"} it is passed on to \code{stats::optim}'s \code{control} 18 | argument and if \code{method = "Nelder-Mead"}, it is passed on to 19 | \code{lme4::Nelder_Mead}'s control argument. If not otherwise specified, 20 | and \code{method = "L-BFGS-B"}, the following arguments are set to 21 | non-default values: \code{fnscale = -1} and \code{lmm = 20}.} 22 | 23 | \item{method}{Character string defining the algorithm to be used for 24 | maximizing the marginal log-likelihood. The default is \code{"L-BFGS-B"}, 25 | which uses the limited memory Broyden-Fletcher-Goldfarb-Shanno algorithm 26 | with box constrained as implemented in \code{stats::optim}. The other 27 | options is \code{"Nelder-Mead"}, which calls the Nelder-Mead algorithm with 28 | box constraints implemented in \code{lme4::Nelder_Mead}. The argument is 29 | case sensitive.} 30 | 31 | \item{maxit_conditional_modes}{Maximum number of iterations in penalized 32 | iteratively reweighted least squares algorithm. Ignored if \code{family = 33 | "gaussian"} for all observations, since then a single step gives the exact 34 | answer.} 35 | 36 | \item{pirls_tol_abs}{Absolute convergence criterion for penalized 37 | iteratively reweighted least squares algorithm. Defaults to 0.01, which 38 | means that when the reduction in marginal likelihood between two iterations 39 | is below 0.01, the iterations stop.} 40 | 41 | \item{reduced_hessian}{Logical value. Defaults to \code{TRUE}, which means 42 | that the full Hessian matrix at the maximum marginal likelihood solution is 43 | computed. If \code{FALSE}, a reduced Hessian matrix with second order 44 | partial derivatives with respect to fixed regression coefficients and 45 | factor loadings. The latter can help is the full Hessian is not positive 46 | definite.} 47 | } 48 | \value{ 49 | Object of class \code{galamm_control}, which typically will be 50 | provided as an argument to \code{\link{galamm}}. 51 | } 52 | \description{ 53 | This function can be called for controling the optimization 54 | procedure used when fitting GALAMMs using \code{\link{galamm}}. 55 | } 56 | \examples{ 57 | # Define control object with quite a high degree of verbosity (trace = 6) 58 | # and using the last 20 BFGS updates to estimate the Hessian in L-BFGS-B. 59 | control <- galamm_control(optim_control = list(trace = 6, lmm = 20)) 60 | 61 | } 62 | \references{ 63 | \insertRef{batesFittingLinearMixedEffects2015}{galamm} 64 | 65 | \insertRef{broydenConvergenceClassDoublerank1970}{galamm} 66 | 67 | \insertRef{byrdLimitedMemoryAlgorithm1995}{galamm} 68 | 69 | \insertRef{fletcherNewApproachVariable1970}{galamm} 70 | 71 | \insertRef{goldfarbFamilyVariablemetricMethods1970}{galamm} 72 | 73 | \insertRef{nelderSimplexMethodFunction1965}{galamm} 74 | 75 | \insertRef{shannoConditioningQuasiNewtonMethods1970}{galamm} 76 | } 77 | \seealso{ 78 | \code{\link[=galamm]{galamm()}} 79 | 80 | Other optimization functions: 81 | \code{\link{extract_optim_parameters.galamm}()} 82 | } 83 | \concept{optimization functions} 84 | -------------------------------------------------------------------------------- /man/hsced.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{hsced} 5 | \alias{hsced} 6 | \title{Example Data with Heteroscedastic Residuals} 7 | \format{ 8 | \subsection{\code{hsced} A data frame with 1200 rows and 5 columns:}{ 9 | 10 | \describe{ 11 | \item{id}{Subject ID.} 12 | \item{age}{Timepoint.} 13 | \item{item}{Item indicator.} 14 | \item{x}{Explanatory variable} 15 | \item{y}{Outcome.} 16 | } 17 | } 18 | } 19 | \usage{ 20 | hsced 21 | } 22 | \description{ 23 | Simulated dataset with residual standard deviation that varies between 24 | items. 25 | } 26 | \references{ 27 | \insertAllCited{} 28 | } 29 | \seealso{ 30 | Other datasets: 31 | \code{\link{cognition}}, 32 | \code{\link{diet}}, 33 | \code{\link{epilep}}, 34 | \code{\link{latent_covariates}}, 35 | \code{\link{latent_covariates_long}}, 36 | \code{\link{lifespan}}, 37 | \code{\link{mresp}}, 38 | \code{\link{mresp_hsced}} 39 | } 40 | \concept{datasets} 41 | \keyword{datasets} 42 | -------------------------------------------------------------------------------- /man/latent_covariates.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{latent_covariates} 5 | \alias{latent_covariates} 6 | \title{Simulated Data with Latent and Observed Covariates Interaction} 7 | \format{ 8 | \subsection{\code{latent_covariates} A data frame with 600 rows and 5 columns:}{ 9 | 10 | \describe{ 11 | \item{id}{Subject ID.} 12 | \item{type}{Type of observation in the \code{y} variable. 13 | If it equals \code{"measurement1"} or \code{"measurement2"} then the 14 | observation is a measurement of the latent variable. If it equals 15 | \code{"response"}, then the observation is the actual response.} 16 | \item{x}{Explanatory variable.} 17 | \item{y}{Observed response. Note, this includes both the actual response, 18 | and the measurements of the latent variable, since mathematically they 19 | are all treated as responses.} 20 | \item{response}{Dummy variable indicating whether the given row is a 21 | response or not.} 22 | } 23 | } 24 | } 25 | \usage{ 26 | latent_covariates 27 | } 28 | \description{ 29 | Simulated dataset for use in examples and testing with a latent covariate 30 | interacting with an observed covariate. 31 | } 32 | \seealso{ 33 | Other datasets: 34 | \code{\link{cognition}}, 35 | \code{\link{diet}}, 36 | \code{\link{epilep}}, 37 | \code{\link{hsced}}, 38 | \code{\link{latent_covariates_long}}, 39 | \code{\link{lifespan}}, 40 | \code{\link{mresp}}, 41 | \code{\link{mresp_hsced}} 42 | } 43 | \concept{datasets} 44 | \keyword{datasets} 45 | -------------------------------------------------------------------------------- /man/latent_covariates_long.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{latent_covariates_long} 5 | \alias{latent_covariates_long} 6 | \title{Simulated Longitudinal Data with Latent and Observed Covariates Interaction} 7 | \format{ 8 | \subsection{\code{latent_covariates_long} A data frame with 800 rows and 5}{ 9 | 10 | columns: 11 | \describe{ 12 | \item{id}{Subject ID.} 13 | \item{type}{Type of observation in the \code{y} variable. 14 | If it equals \code{"measurement1"} or \code{"measurement2"} then the 15 | observation is a measurement of the latent variable. If it equals 16 | \code{"response"}, then the observation is the actual response.} 17 | \item{x}{Explanatory variable.} 18 | \item{y}{Observed response. Note, this includes both the actual response, 19 | and the measurements of the latent variable, since mathematically they 20 | are all treated as responses.} 21 | \item{response}{Dummy variable indicating whether the given row is a 22 | response or not.} 23 | } 24 | } 25 | } 26 | \usage{ 27 | latent_covariates_long 28 | } 29 | \description{ 30 | Simulated dataset for use in examples and testing with a latent covariate 31 | interacting with an observed covariate. In this data, each response has been 32 | measured six times for each subject. 33 | } 34 | \seealso{ 35 | Other datasets: 36 | \code{\link{cognition}}, 37 | \code{\link{diet}}, 38 | \code{\link{epilep}}, 39 | \code{\link{hsced}}, 40 | \code{\link{latent_covariates}}, 41 | \code{\link{lifespan}}, 42 | \code{\link{mresp}}, 43 | \code{\link{mresp_hsced}} 44 | } 45 | \concept{datasets} 46 | \keyword{datasets} 47 | -------------------------------------------------------------------------------- /man/lifespan.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{lifespan} 5 | \alias{lifespan} 6 | \title{Simulated Dataset with Lifespan Trajectories of Three Cognitive Domains} 7 | \format{ 8 | \subsection{\code{lifespan} A data frame with 54,457 rows and 7 columns:}{ 9 | 10 | \describe{ 11 | \item{id}{Subject ID.} 12 | \item{domain}{Cognitive domain being measured. One of \code{"epmem"} for 13 | episodic memory, \code{"wmem"} for working memory and \code{"execfun"} for 14 | executive function/speed.} 15 | \item{timepoint}{Integer indicating the timepoint number.} 16 | \item{age}{Age of participant at the timepoint.} 17 | \item{test}{The particular test at this observation.} 18 | \item{y}{Response. For \code{"epmem"} and \code{"wmem"} this is the number 19 | of successes in 16 trials. For \code{"execfun"} it is the time in seconds 20 | to complete the task.} 21 | \item{retest}{Integer indicating whether the participant has taken the test 22 | at a previous timepoint.} 23 | \item{domainepmem}{Dummy variable for \code{domain=="epmem"}.} 24 | \item{domainwmem}{Dummy variable for \code{domain=="wmem"}.} 25 | \item{domainexecfun}{Dummy variable for \code{domain=="execfun"}.} 26 | } 27 | } 28 | } 29 | \usage{ 30 | lifespan 31 | } 32 | \description{ 33 | This dataset is simulated based on the data used in Section 4.1 of 34 | \insertCite{sorensenLongitudinalModelingAgeDependent2023;textual}{galamm}. 35 | } 36 | \references{ 37 | \insertAllCited{} 38 | } 39 | \seealso{ 40 | Other datasets: 41 | \code{\link{cognition}}, 42 | \code{\link{diet}}, 43 | \code{\link{epilep}}, 44 | \code{\link{hsced}}, 45 | \code{\link{latent_covariates}}, 46 | \code{\link{latent_covariates_long}}, 47 | \code{\link{mresp}}, 48 | \code{\link{mresp_hsced}} 49 | } 50 | \concept{datasets} 51 | \keyword{datasets} 52 | -------------------------------------------------------------------------------- /man/llikAIC.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summary.galamm.R 3 | \name{llikAIC} 4 | \alias{llikAIC} 5 | \title{Extract log likelihood, AIC, and related statistics from a GALAMM} 6 | \usage{ 7 | llikAIC(object) 8 | } 9 | \arguments{ 10 | \item{object}{Object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | } 13 | \value{ 14 | A list containing AIC, BIC, log likelihood, deviance and residual 15 | degrees of freedom. 16 | } 17 | \description{ 18 | This function is assembles the values used by \code{\link{summary.galamm}}. 19 | } 20 | \seealso{ 21 | Other details of model fit: 22 | \code{\link{VarCorr}()}, 23 | \code{\link{coef.galamm}()}, 24 | \code{\link{confint.galamm}()}, 25 | \code{\link{deviance.galamm}()}, 26 | \code{\link{factor_loadings.galamm}()}, 27 | \code{\link{family.galamm}()}, 28 | \code{\link{fitted.galamm}()}, 29 | \code{\link{fixef}()}, 30 | \code{\link{formula.galamm}()}, 31 | \code{\link{logLik.galamm}()}, 32 | \code{\link{nobs.galamm}()}, 33 | \code{\link{predict.galamm}()}, 34 | \code{\link{print.VarCorr.galamm}()}, 35 | \code{\link{ranef.galamm}()}, 36 | \code{\link{residuals.galamm}()}, 37 | \code{\link{response}()}, 38 | \code{\link{sigma.galamm}()}, 39 | \code{\link{vcov.galamm}()} 40 | } 41 | \concept{details of model fit} 42 | \keyword{internal} 43 | -------------------------------------------------------------------------------- /man/logLik.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/logLik.galamm.R 3 | \name{logLik.galamm} 4 | \alias{logLik.galamm} 5 | \title{Extract Log-Likelihood of galamm Object} 6 | \usage{ 7 | \method{logLik}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{Object} 11 | 12 | \item{...}{Other arguments} 13 | } 14 | \value{ 15 | Object of class \code{logLik} 16 | } 17 | \description{ 18 | Extract Log-Likelihood of galamm Object 19 | } 20 | \examples{ 21 | # Linear mixed model with heteroscedastic residuals 22 | mod <- galamm( 23 | formula = y ~ x + (1 | id), 24 | weights = ~ (1 | item), 25 | data = hsced 26 | ) 27 | 28 | # Extract log likelihood 29 | logLik(mod) 30 | 31 | } 32 | \seealso{ 33 | \code{\link[=deviance.galamm]{deviance.galamm()}} for a function returning deviance and 34 | \code{\link[=logLik]{logLik()}} for the generic function. 35 | 36 | Other details of model fit: 37 | \code{\link{VarCorr}()}, 38 | \code{\link{coef.galamm}()}, 39 | \code{\link{confint.galamm}()}, 40 | \code{\link{deviance.galamm}()}, 41 | \code{\link{factor_loadings.galamm}()}, 42 | \code{\link{family.galamm}()}, 43 | \code{\link{fitted.galamm}()}, 44 | \code{\link{fixef}()}, 45 | \code{\link{formula.galamm}()}, 46 | \code{\link{llikAIC}()}, 47 | \code{\link{nobs.galamm}()}, 48 | \code{\link{predict.galamm}()}, 49 | \code{\link{print.VarCorr.galamm}()}, 50 | \code{\link{ranef.galamm}()}, 51 | \code{\link{residuals.galamm}()}, 52 | \code{\link{response}()}, 53 | \code{\link{sigma.galamm}()}, 54 | \code{\link{vcov.galamm}()} 55 | } 56 | \concept{details of model fit} 57 | -------------------------------------------------------------------------------- /man/mresp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{mresp} 5 | \alias{mresp} 6 | \title{Simulated Mixed Response Data} 7 | \format{ 8 | \subsection{\code{mresp} A data frame with 4000 rows and 5 columns:}{ 9 | 10 | \describe{ 11 | \item{id}{Subject ID.} 12 | \item{x}{Predictor variable.} 13 | \item{y}{Response.} 14 | \item{itemgroup}{Factor variable which equals "a" for the normally 15 | distributed responses and "b" for the binomially distributed response 16 | (with 1 trial).} 17 | } 18 | } 19 | } 20 | \usage{ 21 | mresp 22 | } 23 | \description{ 24 | Very basic mixed response dataset with one set of normally distributed 25 | responses and one set of binomially distributed responses. 26 | } 27 | \seealso{ 28 | Other datasets: 29 | \code{\link{cognition}}, 30 | \code{\link{diet}}, 31 | \code{\link{epilep}}, 32 | \code{\link{hsced}}, 33 | \code{\link{latent_covariates}}, 34 | \code{\link{latent_covariates_long}}, 35 | \code{\link{lifespan}}, 36 | \code{\link{mresp_hsced}} 37 | } 38 | \concept{datasets} 39 | \keyword{datasets} 40 | -------------------------------------------------------------------------------- /man/mresp_hsced.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{mresp_hsced} 5 | \alias{mresp_hsced} 6 | \title{Simulated Mixed Response Data with Heteroscedastic Residuals} 7 | \format{ 8 | \subsection{\code{mresp} A data frame with 4000 rows and 5 columns:}{ 9 | 10 | \describe{ 11 | \item{id}{Subject ID.} 12 | \item{x}{Predictor variable.} 13 | \item{y}{Response.} 14 | \item{itemgroup}{Factor variable which equals "a" for the normally 15 | distributed responses and "b" for the binomially distributed response 16 | (with 1 trial).} 17 | \item{grp}{Grouping variable denoting which of the two residual standard 18 | deviations apply. Only relevant for the normally distributed responses.} 19 | \item{isgauss}{Dummy variable indicating whether the observation on the 20 | given line is normally (Gaussian) distributed or not.} 21 | } 22 | } 23 | } 24 | \usage{ 25 | mresp_hsced 26 | } 27 | \description{ 28 | Mixed response dataset with one set of normally distributed 29 | responses and one set of binomially distributed responses. The normally 30 | distributed response follow two different residual standard deviations. 31 | } 32 | \seealso{ 33 | Other datasets: 34 | \code{\link{cognition}}, 35 | \code{\link{diet}}, 36 | \code{\link{epilep}}, 37 | \code{\link{hsced}}, 38 | \code{\link{latent_covariates}}, 39 | \code{\link{latent_covariates_long}}, 40 | \code{\link{lifespan}}, 41 | \code{\link{mresp}} 42 | } 43 | \concept{datasets} 44 | \keyword{datasets} 45 | -------------------------------------------------------------------------------- /man/nobs.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/anova.galamm.R 3 | \name{nobs.galamm} 4 | \alias{nobs.galamm} 5 | \title{Extract the Number of Observations from a galamm Fit} 6 | \usage{ 7 | \method{nobs}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 14 | } 15 | \value{ 16 | A number 17 | } 18 | \description{ 19 | Extract the Number of Observations from a galamm Fit 20 | } 21 | \examples{ 22 | # Example model from lme4 23 | data(sleepstudy, package = "lme4") 24 | fm1 <- galamm(Reaction ~ Days + (Days | Subject), data = sleepstudy) 25 | 26 | # There are 180 observations, which matches the number of rows in sleepstudy 27 | nobs(fm1) 28 | nrow(sleepstudy) 29 | 30 | } 31 | \seealso{ 32 | Other details of model fit: 33 | \code{\link{VarCorr}()}, 34 | \code{\link{coef.galamm}()}, 35 | \code{\link{confint.galamm}()}, 36 | \code{\link{deviance.galamm}()}, 37 | \code{\link{factor_loadings.galamm}()}, 38 | \code{\link{family.galamm}()}, 39 | \code{\link{fitted.galamm}()}, 40 | \code{\link{fixef}()}, 41 | \code{\link{formula.galamm}()}, 42 | \code{\link{llikAIC}()}, 43 | \code{\link{logLik.galamm}()}, 44 | \code{\link{predict.galamm}()}, 45 | \code{\link{print.VarCorr.galamm}()}, 46 | \code{\link{ranef.galamm}()}, 47 | \code{\link{residuals.galamm}()}, 48 | \code{\link{response}()}, 49 | \code{\link{sigma.galamm}()}, 50 | \code{\link{vcov.galamm}()} 51 | } 52 | \concept{details of model fit} 53 | -------------------------------------------------------------------------------- /man/plot.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.galamm.R 3 | \name{plot.galamm} 4 | \alias{plot.galamm} 5 | \title{Diagnostic plots for galamm objects} 6 | \usage{ 7 | \method{plot}{galamm}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{An object of class \code{galamm} returned from \code{\link{galamm}}.} 11 | 12 | \item{...}{Optional arguments passed on to the \code{plot} function.} 13 | } 14 | \value{ 15 | A plot is displayed. 16 | } 17 | \description{ 18 | Diagnostic plots for galamm objects 19 | } 20 | \examples{ 21 | # Linear mixed model example from lme4 22 | data("sleepstudy", package = "lme4") 23 | mod <- galamm(Reaction ~ Days + (Days | Subject), data = sleepstudy) 24 | 25 | # Diagnostic plot 26 | plot(mod) 27 | 28 | } 29 | \seealso{ 30 | \code{\link[=residuals.galamm]{residuals.galamm()}} for extracting residuals and \code{\link[=plot]{plot()}} for the 31 | generic function. 32 | 33 | Other summary functions: 34 | \code{\link{anova.galamm}()}, 35 | \code{\link{plot_smooth.galamm}()}, 36 | \code{\link{print.galamm}()}, 37 | \code{\link{print.summary.galamm}()}, 38 | \code{\link{summary.galamm}()} 39 | } 40 | \concept{summary functions} 41 | -------------------------------------------------------------------------------- /man/plot_smooth.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_smooth.R 3 | \name{plot_smooth.galamm} 4 | \alias{plot_smooth.galamm} 5 | \alias{plot_smooth} 6 | \title{Plot smooth terms for galamm fits} 7 | \usage{ 8 | \method{plot_smooth}{galamm}(object, ...) 9 | } 10 | \arguments{ 11 | \item{object}{Object of class \code{galamm} returned from 12 | \code{\link{galamm}}.} 13 | 14 | \item{...}{Other optional arguments, passed on to \code{mgcv::plot.gam}.} 15 | } 16 | \value{ 17 | A plot is displayed on the screen. 18 | } 19 | \description{ 20 | Plots smooth terms of a fitted \code{galamm} object. This function is a thin 21 | wrapper around \code{mgcv::plot.gam} 22 | \insertCite{woodGeneralizedAdditiveModels2017}{galamm}. 23 | } 24 | \examples{ 25 | # Generalized additive mixed model with factor structures ------------------- 26 | 27 | # The cognition dataset contains simulated measurements of three latent 28 | # time-dependent processes, corresponding to individuals' abilities in 29 | # cognitive domains. We focus here on the first domain, and take a single 30 | # random timepoint per person: 31 | dat <- subset(cognition, domain == 1) 32 | dat <- split(dat, f = dat$id) 33 | dat <- lapply(dat, function(x) x[x$timepoint \%in\% sample(x$timepoint, 1), ]) 34 | dat <- do.call(rbind, dat) 35 | dat$item <- factor(dat$item) 36 | 37 | # At each timepoint there are three items measuring ability in the cognitive 38 | # domain. We fix the factor loading for the first measurement to one, and 39 | # estimate the remaining two. This is specified in the loading matrix. 40 | loading_matrix <- matrix(c(1, NA, NA), ncol = 1) 41 | 42 | # We can now estimate the model. 43 | mod <- galamm( 44 | formula = y ~ 0 + item + sl(x, factor = "loading") + 45 | (0 + loading | id), 46 | data = dat, 47 | load.var = "item", 48 | lambda = loading_matrix, 49 | factor = "loading" 50 | ) 51 | 52 | # We can plot the estimated smooth term 53 | plot_smooth(mod, shade = TRUE) 54 | 55 | # We can turn off the rug at the bottom 56 | plot_smooth(mod, shade = TRUE, rug = FALSE) 57 | 58 | } 59 | \references{ 60 | \insertAllCited{} 61 | } 62 | \seealso{ 63 | Other summary functions: 64 | \code{\link{anova.galamm}()}, 65 | \code{\link{plot.galamm}()}, 66 | \code{\link{print.galamm}()}, 67 | \code{\link{print.summary.galamm}()}, 68 | \code{\link{summary.galamm}()} 69 | } 70 | \concept{summary functions} 71 | -------------------------------------------------------------------------------- /man/predict.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/predict.galamm.R 3 | \name{predict.galamm} 4 | \alias{predict.galamm} 5 | \title{Predictions from a model at new data values} 6 | \usage{ 7 | \method{predict}{galamm}(object, newdata = NULL, type = c("link", "response"), ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{newdata}{Data from for which to evaluate predictions, in a 14 | \code{data.frame}. Defaults to "NULL", which means that the predictions are 15 | evaluate at the data used to fit the model.} 16 | 17 | \item{type}{Character argument specifying the type of prediction object to be 18 | returned. Case sensitive.} 19 | 20 | \item{...}{Optional arguments passed on to other methods. Currently used for 21 | models with smooth terms, for which these arguments are forwarded to 22 | \code{mgcv::predict.gam}.} 23 | } 24 | \value{ 25 | A numeric vector of predicted values. 26 | } 27 | \description{ 28 | Predictions are given at the population level, i.e., with random 29 | effects set to zero. For fitted models including random effects, see 30 | \code{\link{fitted.galamm}}. For mixed response models, only predictions on 31 | the scale of the linear predictors is supported. 32 | } 33 | \examples{ 34 | # Poisson GLMM 35 | count_mod <- galamm( 36 | formula = y ~ lbas * treat + lage + v4 + (1 | subj), 37 | data = epilep, family = poisson 38 | ) 39 | 40 | # Plot response versus link: 41 | plot( 42 | predict(count_mod, type = "link"), 43 | predict(count_mod, type = "response") 44 | ) 45 | 46 | # Predict on a new dataset 47 | nd <- data.frame(lbas = c(.3, .2), treat = c(0, 1), lage = 0.2, v4 = -.2) 48 | predict(count_mod, newdata = nd) 49 | predict(count_mod, newdata = nd, type = "response") 50 | 51 | } 52 | \seealso{ 53 | \code{\link[=fitted.galamm]{fitted.galamm()}} for model fits, \code{\link[=residuals.galamm]{residuals.galamm()}} for 54 | residuals, and \code{\link[=predict]{predict()}} for the generic function. 55 | 56 | Other details of model fit: 57 | \code{\link{VarCorr}()}, 58 | \code{\link{coef.galamm}()}, 59 | \code{\link{confint.galamm}()}, 60 | \code{\link{deviance.galamm}()}, 61 | \code{\link{factor_loadings.galamm}()}, 62 | \code{\link{family.galamm}()}, 63 | \code{\link{fitted.galamm}()}, 64 | \code{\link{fixef}()}, 65 | \code{\link{formula.galamm}()}, 66 | \code{\link{llikAIC}()}, 67 | \code{\link{logLik.galamm}()}, 68 | \code{\link{nobs.galamm}()}, 69 | \code{\link{print.VarCorr.galamm}()}, 70 | \code{\link{ranef.galamm}()}, 71 | \code{\link{residuals.galamm}()}, 72 | \code{\link{response}()}, 73 | \code{\link{sigma.galamm}()}, 74 | \code{\link{vcov.galamm}()} 75 | } 76 | \concept{details of model fit} 77 | -------------------------------------------------------------------------------- /man/print.VarCorr.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/VarCorr.R 3 | \name{print.VarCorr.galamm} 4 | \alias{print.VarCorr.galamm} 5 | \title{Print method for variance-covariance objects} 6 | \usage{ 7 | \method{print}{VarCorr.galamm}( 8 | x, 9 | digits = max(3, getOption("digits") - 2), 10 | comp = c("Std.Dev.", "Variance"), 11 | corr = any(comp == "Std.Dev."), 12 | ... 13 | ) 14 | } 15 | \arguments{ 16 | \item{x}{An object of class \code{c("VarCorr.galamm", "VarCorr.merMod")}, 17 | returned from \code{\link{VarCorr.galamm}}.} 18 | 19 | \item{digits}{Optional arguments specifying number of digits to use when 20 | printing.} 21 | 22 | \item{comp}{Character vector of length 1 or 2 specifying which variance 23 | components to print. Case sensitive. Can take one of the values "Std.Dev." 24 | and "Variance".} 25 | 26 | \item{corr}{Logical value indicating whether covariances or correlations 27 | should be printed.} 28 | 29 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 30 | } 31 | \value{ 32 | The variance-covariance information is printed to the console and the 33 | argument \code{x} is silently returned. 34 | } 35 | \description{ 36 | Print method for variance-covariance objects 37 | } 38 | \examples{ 39 | # Linear mixed model with heteroscedastic residuals 40 | mod <- galamm( 41 | formula = y ~ x + (1 | id), 42 | weights = ~ (1 | item), 43 | data = hsced 44 | ) 45 | 46 | # Extract information on variance and covariance 47 | VarCorr(mod) 48 | 49 | } 50 | \references{ 51 | \insertRef{batesFittingLinearMixedEffects2015}{galamm} 52 | } 53 | \seealso{ 54 | \code{\link[=VarCorr.galamm]{VarCorr.galamm()}} for the function creating the variance-covariance 55 | objects. 56 | 57 | Other details of model fit: 58 | \code{\link{VarCorr}()}, 59 | \code{\link{coef.galamm}()}, 60 | \code{\link{confint.galamm}()}, 61 | \code{\link{deviance.galamm}()}, 62 | \code{\link{factor_loadings.galamm}()}, 63 | \code{\link{family.galamm}()}, 64 | \code{\link{fitted.galamm}()}, 65 | \code{\link{fixef}()}, 66 | \code{\link{formula.galamm}()}, 67 | \code{\link{llikAIC}()}, 68 | \code{\link{logLik.galamm}()}, 69 | \code{\link{nobs.galamm}()}, 70 | \code{\link{predict.galamm}()}, 71 | \code{\link{ranef.galamm}()}, 72 | \code{\link{residuals.galamm}()}, 73 | \code{\link{response}()}, 74 | \code{\link{sigma.galamm}()}, 75 | \code{\link{vcov.galamm}()} 76 | } 77 | \author{ 78 | This function is derived from \code{lme4:::print.VarCorr.merMod} 79 | written by Douglas M. Bates, Martin Maechler, Ben Bolker, and Steve Walker. 80 | } 81 | \concept{details of model fit} 82 | -------------------------------------------------------------------------------- /man/print.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summary.galamm.R 3 | \name{print.galamm} 4 | \alias{print.galamm} 5 | \title{Print method for GALAMM fits} 6 | \usage{ 7 | \method{print}{galamm}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{An object of class \code{galamm} returned from \code{\link{galamm}}.} 11 | 12 | \item{...}{Further arguments passed on to other methods. Currently not used.} 13 | } 14 | \value{ 15 | Summary printed to screen. Invisibly returns the argument \code{x}. 16 | } 17 | \description{ 18 | Print method for GALAMM fits 19 | } 20 | \examples{ 21 | # Linear mixed model with heteroscedastic residuals 22 | mod <- galamm( 23 | formula = y ~ x + (1 | id), 24 | weights = ~ (1 | item), 25 | data = hsced 26 | ) 27 | 28 | print(mod) 29 | 30 | } 31 | \seealso{ 32 | \code{\link[=summary.galamm]{summary.galamm()}} for the summary function and \code{\link[=print]{print()}} for the 33 | generic. 34 | 35 | Other summary functions: 36 | \code{\link{anova.galamm}()}, 37 | \code{\link{plot.galamm}()}, 38 | \code{\link{plot_smooth.galamm}()}, 39 | \code{\link{print.summary.galamm}()}, 40 | \code{\link{summary.galamm}()} 41 | } 42 | \concept{summary functions} 43 | -------------------------------------------------------------------------------- /man/print.summary.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summary.galamm.R 3 | \name{print.summary.galamm} 4 | \alias{print.summary.galamm} 5 | \title{Print method for summary GALAMM fits} 6 | \usage{ 7 | \method{print}{summary.galamm}(x, digits = max(3, getOption("digits") - 3), ...) 8 | } 9 | \arguments{ 10 | \item{x}{An object of class \code{summary.galamm} returned from 11 | \code{\link{summary.galamm}}.} 12 | 13 | \item{digits}{Number of digits to present in outputs.} 14 | 15 | \item{...}{Further arguments passed on to other methods. Currently used by 16 | \code{stats::printCoefmat} for printing approximate significance of smooth 17 | terms.} 18 | } 19 | \value{ 20 | Summary printed to screen. Invisibly returns the argument \code{x}. 21 | } 22 | \description{ 23 | Print method for summary GALAMM fits 24 | } 25 | \examples{ 26 | # Linear mixed model with heteroscedastic residuals 27 | mod <- galamm( 28 | formula = y ~ x + (1 | id), 29 | weights = ~ (1 | item), 30 | data = hsced 31 | ) 32 | 33 | summary(mod) 34 | 35 | } 36 | \references{ 37 | \insertAllCited{} 38 | } 39 | \seealso{ 40 | \code{\link[=summary.galamm]{summary.galamm()}} for the summary function and \code{\link[=print]{print()}} for the 41 | generic function. 42 | 43 | Other summary functions: 44 | \code{\link{anova.galamm}()}, 45 | \code{\link{plot.galamm}()}, 46 | \code{\link{plot_smooth.galamm}()}, 47 | \code{\link{print.galamm}()}, 48 | \code{\link{summary.galamm}()} 49 | } 50 | \author{ 51 | Some of the code for producing summary information has been derived 52 | from the summary methods of \code{mgcv} (author: Simon Wood) and 53 | \code{lme4} \insertCite{batesFittingLinearMixedEffects2015}{galamm} 54 | (authors: Douglas M. Bates, Martin Maechler, Ben Bolker, and Steve Walker). 55 | } 56 | \concept{summary functions} 57 | -------------------------------------------------------------------------------- /man/ranef.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ranef.R 3 | \name{ranef.galamm} 4 | \alias{ranef.galamm} 5 | \alias{ranef} 6 | \title{Extract random effects from galamm object.} 7 | \usage{ 8 | \method{ranef}{galamm}(object, ...) 9 | } 10 | \arguments{ 11 | \item{object}{An object of class \code{galamm}, returned from 12 | \code{\link{galamm}}.} 13 | 14 | \item{...}{Optional parameters passed on to other methods. Currently not 15 | used.} 16 | } 17 | \value{ 18 | An object of class \code{ranef.galamm}, containing the requested 19 | random effects. 20 | } 21 | \description{ 22 | Extract random effects from galamm object. 23 | } 24 | \examples{ 25 | # Poisson GLMM 26 | count_mod <- galamm( 27 | formula = y ~ lbas * treat + lage + v4 + (1 | subj), 28 | data = epilep, family = poisson 29 | ) 30 | 31 | # Extract random effects 32 | ranef(count_mod) 33 | 34 | } 35 | \references{ 36 | \insertRef{batesFittingLinearMixedEffects2015}{galamm} 37 | } 38 | \seealso{ 39 | \code{\link[=fixef.galamm]{fixef.galamm()}} for fixed effects and \code{\link[=coef.galamm]{coef.galamm()}} for 40 | coefficients more generally. 41 | 42 | Other details of model fit: 43 | \code{\link{VarCorr}()}, 44 | \code{\link{coef.galamm}()}, 45 | \code{\link{confint.galamm}()}, 46 | \code{\link{deviance.galamm}()}, 47 | \code{\link{factor_loadings.galamm}()}, 48 | \code{\link{family.galamm}()}, 49 | \code{\link{fitted.galamm}()}, 50 | \code{\link{fixef}()}, 51 | \code{\link{formula.galamm}()}, 52 | \code{\link{llikAIC}()}, 53 | \code{\link{logLik.galamm}()}, 54 | \code{\link{nobs.galamm}()}, 55 | \code{\link{predict.galamm}()}, 56 | \code{\link{print.VarCorr.galamm}()}, 57 | \code{\link{residuals.galamm}()}, 58 | \code{\link{response}()}, 59 | \code{\link{sigma.galamm}()}, 60 | \code{\link{vcov.galamm}()} 61 | } 62 | \author{ 63 | This function is derived from \code{lme4::ranef.merMod}, written by 64 | Douglas Bates, Martin Maechler, Ben Bolker, Steve Walker. 65 | } 66 | \concept{details of model fit} 67 | -------------------------------------------------------------------------------- /man/residuals.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/residuals.galamm.R 3 | \name{residuals.galamm} 4 | \alias{residuals.galamm} 5 | \title{Residuals of galamm objects} 6 | \usage{ 7 | \method{residuals}{galamm}(object, type = c("pearson", "deviance"), ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{type}{Character of length one describing the type of residuals to be 14 | returned. One of \code{"pearson"} and \code{"deviance"}. Argument is case 15 | sensitive.} 16 | 17 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 18 | } 19 | \value{ 20 | Numeric vector of residual values. 21 | } 22 | \description{ 23 | Residuals of galamm objects 24 | } 25 | \examples{ 26 | # Poisson GLMM 27 | count_mod <- galamm( 28 | formula = y ~ lbas * treat + lage + v4 + (1 | subj), 29 | data = epilep, family = poisson 30 | ) 31 | 32 | # Extract residuals 33 | residuals(count_mod) 34 | 35 | } 36 | \seealso{ 37 | \code{\link[=fitted.galamm]{fitted.galamm()}} for model fitted values, \code{\link[=predict.galamm]{predict.galamm()}} for 38 | model predictions, and \code{\link[=plot.galamm]{plot.galamm()}} for diagnostic plots. The generic 39 | function is \code{\link[=residuals]{residuals()}}. 40 | 41 | Other details of model fit: 42 | \code{\link{VarCorr}()}, 43 | \code{\link{coef.galamm}()}, 44 | \code{\link{confint.galamm}()}, 45 | \code{\link{deviance.galamm}()}, 46 | \code{\link{factor_loadings.galamm}()}, 47 | \code{\link{family.galamm}()}, 48 | \code{\link{fitted.galamm}()}, 49 | \code{\link{fixef}()}, 50 | \code{\link{formula.galamm}()}, 51 | \code{\link{llikAIC}()}, 52 | \code{\link{logLik.galamm}()}, 53 | \code{\link{nobs.galamm}()}, 54 | \code{\link{predict.galamm}()}, 55 | \code{\link{print.VarCorr.galamm}()}, 56 | \code{\link{ranef.galamm}()}, 57 | \code{\link{response}()}, 58 | \code{\link{sigma.galamm}()}, 59 | \code{\link{vcov.galamm}()} 60 | } 61 | \concept{details of model fit} 62 | -------------------------------------------------------------------------------- /man/response.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/response.R 3 | \name{response} 4 | \alias{response} 5 | \title{Extract response values} 6 | \usage{ 7 | response(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{...}{Optional arguments passed on to other methods. Currently not used.} 14 | } 15 | \value{ 16 | A numerical vector with fit response values for each row in the input 17 | data. 18 | } 19 | \description{ 20 | Extracts response values from a model. 21 | } 22 | \examples{ 23 | # Linear mixed model with heteroscedastic residuals 24 | mod <- galamm( 25 | formula = y ~ x + (1 | id), 26 | weights = ~ (1 | item), 27 | data = hsced 28 | ) 29 | 30 | # Plot response versus fitted values 31 | plot(fitted(mod), response(mod)) 32 | 33 | } 34 | \seealso{ 35 | Other details of model fit: 36 | \code{\link{VarCorr}()}, 37 | \code{\link{coef.galamm}()}, 38 | \code{\link{confint.galamm}()}, 39 | \code{\link{deviance.galamm}()}, 40 | \code{\link{factor_loadings.galamm}()}, 41 | \code{\link{family.galamm}()}, 42 | \code{\link{fitted.galamm}()}, 43 | \code{\link{fixef}()}, 44 | \code{\link{formula.galamm}()}, 45 | \code{\link{llikAIC}()}, 46 | \code{\link{logLik.galamm}()}, 47 | \code{\link{nobs.galamm}()}, 48 | \code{\link{predict.galamm}()}, 49 | \code{\link{print.VarCorr.galamm}()}, 50 | \code{\link{ranef.galamm}()}, 51 | \code{\link{residuals.galamm}()}, 52 | \code{\link{sigma.galamm}()}, 53 | \code{\link{vcov.galamm}()} 54 | } 55 | \concept{details of model fit} 56 | -------------------------------------------------------------------------------- /man/sigma.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sigma.R 3 | \name{sigma.galamm} 4 | \alias{sigma.galamm} 5 | \title{Extract square root of dispersion parameter from galamm object} 6 | \usage{ 7 | \method{sigma}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm}, returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{...}{Optional parameters passed on to other methods. Currently not 14 | used.} 15 | } 16 | \value{ 17 | The square root of one or more dispersion parameters. 18 | } 19 | \description{ 20 | Extracts the square root of the dispersion parameter(s) from an object of 21 | class \code{galamm}, returned from \code{\link{galamm}}. In the case of 22 | conditionally Gaussian responses, this is the residual standard deviation. 23 | When there are multiple dispersion parameters, e.g., with mixed response 24 | type models, the square root of all of them are returned in a numeric vector. 25 | } 26 | \examples{ 27 | # Linear mixed model with heteroscedastic residuals 28 | mod <- galamm( 29 | formula = y ~ x + (1 | id), 30 | weights = ~ (1 | item), 31 | data = hsced 32 | ) 33 | 34 | # Extract residual standard deviation. 35 | sigma(mod) 36 | 37 | # The residual standard deviation applies to the base case. The variance 38 | # function shown in the model output shows the estimated multiplier for 39 | # various grouping levels: 40 | summary(mod) 41 | 42 | } 43 | \seealso{ 44 | \code{\link[=galamm]{galamm()}} 45 | 46 | Other details of model fit: 47 | \code{\link{VarCorr}()}, 48 | \code{\link{coef.galamm}()}, 49 | \code{\link{confint.galamm}()}, 50 | \code{\link{deviance.galamm}()}, 51 | \code{\link{factor_loadings.galamm}()}, 52 | \code{\link{family.galamm}()}, 53 | \code{\link{fitted.galamm}()}, 54 | \code{\link{fixef}()}, 55 | \code{\link{formula.galamm}()}, 56 | \code{\link{llikAIC}()}, 57 | \code{\link{logLik.galamm}()}, 58 | \code{\link{nobs.galamm}()}, 59 | \code{\link{predict.galamm}()}, 60 | \code{\link{print.VarCorr.galamm}()}, 61 | \code{\link{ranef.galamm}()}, 62 | \code{\link{residuals.galamm}()}, 63 | \code{\link{response}()}, 64 | \code{\link{vcov.galamm}()} 65 | } 66 | \concept{details of model fit} 67 | -------------------------------------------------------------------------------- /man/sl.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/smooths.R 3 | \name{s} 4 | \alias{s} 5 | \alias{sl} 6 | \title{Set up smooth term with factor loading} 7 | \usage{ 8 | sl(..., factor = NULL) 9 | } 10 | \arguments{ 11 | \item{...}{Arguments passed on to \code{mgcv::s}.} 12 | 13 | \item{factor}{Optional character argument specifying the loading variable. 14 | Case sensitive.} 15 | } 16 | \value{ 17 | An object of class \code{xx.smooth.spec}, where \code{xx} is a basis 18 | identifying code given by the \code{bs} argument of \code{s}. It differs 19 | from the smooth returned by \code{mgcv::s} in that it has an additional 20 | attribute named \code{"factor"} which specifies any factor loading which 21 | this smooth term should be multiplied with in order to produce the observed 22 | outcome. 23 | } 24 | \description{ 25 | This is a very thin wrapper around \code{mgcv::s}. It enables 26 | the specification of loading variables for smooth terms. The last letter "l", 27 | which stands for "loading", has been added to avoid namespace conflicts with 28 | \code{mgcv} and \code{gamm4}. 29 | } 30 | \details{ 31 | The documentation of the function \code{mgcv::s} should be consulted 32 | for details on how to properly set up smooth terms. In particular, note 33 | that these terms distinguish between ordered and unordered factor terms 34 | in the \code{by} variable, which can be provided in \code{...} and is 35 | forwarded to \code{mgcv::s}. 36 | } 37 | \examples{ 38 | # Linear mixed model with factor structures 39 | dat <- subset(cognition, domain == 1 & timepoint == 1) 40 | loading_matrix <- matrix(c(1, NA, NA), ncol = 1) 41 | 42 | 43 | # Model with four thin-plate regression splines as basis functions 44 | mod <- galamm( 45 | formula = y ~ 0 + item + sl(x, k = 4, factor = "loading"), 46 | data = dat, 47 | load.var = "item", 48 | lambda = loading_matrix, 49 | factor = "loading" 50 | ) 51 | 52 | # Model with four cubic regression splines as basis functions 53 | mod <- galamm( 54 | formula = y ~ 0 + item + 55 | sl(x, bs = "cr", k = 4, factor = "loading"), 56 | data = dat, 57 | load.var = "item", 58 | lambda = loading_matrix, 59 | factor = "loading" 60 | ) 61 | 62 | } 63 | \references{ 64 | \insertRef{woodThinPlateRegression2003}{galamm} 65 | 66 | \insertRef{woodGeneralizedAdditiveModels2017}{galamm} 67 | } 68 | \seealso{ 69 | Other modeling functions: 70 | \code{\link{galamm}()}, 71 | \code{\link{t2}()} 72 | } 73 | \concept{modeling functions} 74 | -------------------------------------------------------------------------------- /man/summary.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summary.galamm.R 3 | \name{summary.galamm} 4 | \alias{summary.galamm} 5 | \title{Summarizing GALAMM fits} 6 | \usage{ 7 | \method{summary}{galamm}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{An object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{...}{Further arguments passed on to other methods. Currently not used.} 14 | } 15 | \value{ 16 | A list of summary statistics of the fitted model of class 17 | \code{summary.galamm}, containing the following elements: 18 | \itemize{ 19 | \item \code{AICtab} a table of model fit measures, returned by 20 | \code{\link{llikAIC}}. 21 | \item \code{call} the matched call used when fitting the model. 22 | \item \code{fixef} a matrix with fixed effect estimated, returned by 23 | \code{\link{fixef}}. 24 | \item \code{gam} List containing information about smooth terms in the model. If 25 | no smooth terms are contained in the model, then it is a list of length 26 | zero. 27 | \item \code{model} a list with various elements related to the model setup and 28 | fit. See \code{?galamm} for details. 29 | \item \code{parameters} A list object with model parameters and related 30 | information. See \code{?galamm} for details. 31 | \item \code{Lambda} An object containing the estimated factor loadings. Returned 32 | from \code{\link{factor_loadings.galamm}}. If there are no estimated factor 33 | loadings, then this object is \code{NULL}. 34 | \item \code{random_effects} a list containing the random effects. 35 | See \code{?galamm} for details. 36 | \item \code{VarCorr} An object of class \code{VarCorr.galamm}, returned from 37 | \code{\link{VarCorr.galamm}}. 38 | \item \code{weights} An object containing information about estimated variance 39 | functions, when there are heteroscedastic residuals. Otherwise the object 40 | is \code{NULL}. 41 | } 42 | } 43 | \description{ 44 | Summary method for class "galamm". 45 | } 46 | \examples{ 47 | # Linear mixed model with heteroscedastic residuals 48 | mod <- galamm( 49 | formula = y ~ x + (1 | id), 50 | weights = ~ (1 | item), 51 | data = hsced 52 | ) 53 | 54 | summary(mod) 55 | 56 | } 57 | \seealso{ 58 | \code{\link[=print.summary.galamm]{print.summary.galamm()}} for the print method and \code{\link[=summary]{summary()}} for 59 | the generic. 60 | 61 | Other summary functions: 62 | \code{\link{anova.galamm}()}, 63 | \code{\link{plot.galamm}()}, 64 | \code{\link{plot_smooth.galamm}()}, 65 | \code{\link{print.galamm}()}, 66 | \code{\link{print.summary.galamm}()} 67 | } 68 | \author{ 69 | Some of the code for producing summary information has been derived 70 | from the summary methods of \code{mgcv} (author: Simon Wood) and 71 | \code{lme4} \insertCite{batesFittingLinearMixedEffects2015}{galamm} 72 | (authors: Douglas M. Bates, Martin Maechler, Ben Bolker, and Steve Walker). 73 | } 74 | \concept{summary functions} 75 | -------------------------------------------------------------------------------- /man/t2l.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/smooths.R 3 | \name{t2} 4 | \alias{t2} 5 | \alias{t2l} 6 | \title{Set up smooth term with factor loading} 7 | \usage{ 8 | t2l(..., factor = NULL) 9 | } 10 | \arguments{ 11 | \item{...}{Arguments passed on to \code{mgcv::t2}.} 12 | 13 | \item{factor}{Optional character of length one specifying the loading 14 | variable. Case sensitive.} 15 | } 16 | \value{ 17 | An object of class \code{xx.smooth.spec}, where \code{xx} is a basis 18 | identifying code given by the \code{bs} argument of \code{t2}. It differs 19 | from the smooth returned by \code{mgcv::s} in that it has an additional 20 | attribute named \code{"factor"} which specifies any factor loading which 21 | this smooth term should be multiplied with in order to produce the observed 22 | outcome. 23 | } 24 | \description{ 25 | This is a very thin wrapper around \code{mgcv::t2}. It enables 26 | the specification of loading variables for smooth terms. The last letter 27 | "l", which stands for "loading", has been added to avoid namespace 28 | conflicts with \code{mgcv} and \code{gamm4}. 29 | } 30 | \details{ 31 | The documentation of the function \code{mgcv::t2} should be consulted 32 | for details on how to properly set up smooth terms. In particular, note 33 | that these terms distinguish between ordered and unordered factor terms 34 | in the \code{by} variable, which can be provided in \code{...} and is 35 | forwarded to \code{mgcv::t2}. 36 | } 37 | \examples{ 38 | # Linear mixed model with factor structures 39 | dat <- subset(cognition, domain == 1 & timepoint == 1) 40 | loading_matrix <- matrix(c(1, NA, NA), ncol = 1) 41 | 42 | # Model with four cubic regression splines as basis functions 43 | mod <- galamm( 44 | formula = y ~ 0 + item + t2l(x, k = 4, factor = "loading"), 45 | data = dat, 46 | load.var = "item", 47 | lambda = loading_matrix, 48 | factor = "loading" 49 | ) 50 | 51 | # Model with four thin-plate regression splines as basis functions 52 | mod <- galamm( 53 | formula = y ~ 0 + item + 54 | t2l(x, bs = "tp", k = 4, factor = "loading"), 55 | data = dat, 56 | load.var = "item", 57 | lambda = loading_matrix, 58 | factor = "loading" 59 | ) 60 | 61 | } 62 | \references{ 63 | \insertRef{woodThinPlateRegression2003}{galamm} 64 | 65 | \insertRef{woodGeneralizedAdditiveModels2017}{galamm} 66 | } 67 | \seealso{ 68 | Other modeling functions: 69 | \code{\link{galamm}()}, 70 | \code{\link{s}()} 71 | } 72 | \concept{modeling functions} 73 | -------------------------------------------------------------------------------- /man/vcov.galamm.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vcov.R 3 | \name{vcov.galamm} 4 | \alias{vcov.galamm} 5 | \title{Calculate variance-covariance matrix for GALAMM fit} 6 | \usage{ 7 | \method{vcov}{galamm}(object, parm = "beta", ...) 8 | } 9 | \arguments{ 10 | \item{object}{Object of class \code{galamm} returned from 11 | \code{\link{galamm}}.} 12 | 13 | \item{parm}{The parameters for which the variance-covariance matrix should be 14 | calculated. Character vector with one or more of the elements "theta", 15 | "beta", "lambda", and "weights". Can also be an integer vector. When given 16 | as a character, it must be in only lowercase letters.} 17 | 18 | \item{...}{Further arguments passed on to other methods. Currently not used.} 19 | } 20 | \value{ 21 | A variance-covariance matrix. 22 | } 23 | \description{ 24 | Calculate variance-covariance matrix for GALAMM fit 25 | } 26 | \examples{ 27 | # Linear mixed model with heteroscedastic residuals 28 | mod <- galamm( 29 | formula = y ~ x + (1 | id), 30 | weights = ~ (1 | item), 31 | data = hsced 32 | ) 33 | 34 | # Extract covariance matrix for fixed regression coefficients 35 | vcov(mod, parm = "beta") 36 | 37 | # and then for weights, which gives us the variance. 38 | vcov(mod, parm = "weights") 39 | 40 | } 41 | \seealso{ 42 | \code{\link[=confint.galamm]{confint.galamm()}} for the method computing confidence intervals. 43 | See \code{\link[=vcov]{vcov()}} for the generic function. 44 | 45 | Other details of model fit: 46 | \code{\link{VarCorr}()}, 47 | \code{\link{coef.galamm}()}, 48 | \code{\link{confint.galamm}()}, 49 | \code{\link{deviance.galamm}()}, 50 | \code{\link{factor_loadings.galamm}()}, 51 | \code{\link{family.galamm}()}, 52 | \code{\link{fitted.galamm}()}, 53 | \code{\link{fixef}()}, 54 | \code{\link{formula.galamm}()}, 55 | \code{\link{llikAIC}()}, 56 | \code{\link{logLik.galamm}()}, 57 | \code{\link{nobs.galamm}()}, 58 | \code{\link{predict.galamm}()}, 59 | \code{\link{print.VarCorr.galamm}()}, 60 | \code{\link{ranef.galamm}()}, 61 | \code{\link{residuals.galamm}()}, 62 | \code{\link{response}()}, 63 | \code{\link{sigma.galamm}()} 64 | } 65 | \concept{details of model fit} 66 | -------------------------------------------------------------------------------- /news.md: -------------------------------------------------------------------------------- 1 | # galamm 0.2.2 2 | 3 | - Internal fix to avoid warning about uninitialized variables. 4 | - New function response() returns the response used for fitting the model. 5 | - New print.galamm() function which is an alias for print(summary(galamm_obj)). 6 | - Rank deficient fixed effect matrices now leads to an error. Previously only 7 | a message was written that the redundant columns were dropped. 8 | 9 | 10 | # galamm version 0.2.1 11 | 12 | - Software paper in Multivariate Behavioral Research has been added to the 13 | recommended citation. 14 | 15 | # galamm version 0.2.0 16 | 17 | - The print.summary.galamm() method does no longer print residual percentiles 18 | with mixed response models. The version implemented until now had a bug, and 19 | it is not clear how to present this information in a useful way. 20 | - Fixed bug causing galamm() to fail with mixed response types, when the first 21 | argument to "family" was not "gaussian". 22 | - BREAKING CHANGE: argument "factor", "factor_interaction" and "lambda" to 23 | galamm should no longer be enclosed in a list. 24 | - A vignette investigating computational scalability has been added. 25 | - formula.galamm() method has been added, inheriting from stats::formula(). 26 | - nobs.galamm() function is now exported. 27 | - na.action argument has been added to galamm(). 28 | - input validation has been extended. 29 | - all internal functions have been documented, using the @noRd tag to suppress 30 | generation of markdown. 31 | 32 | # galamm version 0.1.1 33 | 34 | - Fixed bug causing galamm to fail on R4.2.3. 35 | - Fixed memory issues in C++ code. 36 | - In the smooth terms sl() and t2(), the argument 'load.var' has been renamed to 37 | 'factor', to correspond with the remaining factor arguments. 38 | 39 | # galamm version 0.1.0 40 | 41 | Initial version. 42 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /rebuild-long-running-vignettes.R: -------------------------------------------------------------------------------- 1 | old_wd <- getwd() 2 | 3 | setwd("vignettes-raw/") 4 | knitr::knit("lmm_factor.Rmd", output = "../vignettes/lmm_factor.Rmd") 5 | knitr::knit("glmm_factor.Rmd", output = "../vignettes/glmm_factor.Rmd") 6 | knitr::knit("mixed_response.Rmd", output = "../vignettes/mixed_response.Rmd") 7 | knitr::knit("lmm_heteroscedastic.Rmd", output = "../vignettes/lmm_heteroscedastic.Rmd") 8 | knitr::knit("semiparametric.Rmd", output = "../vignettes/semiparametric.Rmd") 9 | knitr::knit("optimization.Rmd", output = "../vignettes/optimization.Rmd") 10 | knitr::knit("latent_observed_interaction.Rmd", output = "../vignettes/latent_observed_interaction.Rmd") 11 | knitr::knit("scaling.Rmd", output = "../vignettes/scaling.Rmd") 12 | 13 | imgs <- list.files(pattern = "\\.png$") 14 | imgs_new <- file.path("..", "vignettes", imgs) 15 | file.rename(imgs, imgs_new) 16 | setwd(old_wd) 17 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.dll 4 | -------------------------------------------------------------------------------- /src/Makevars: -------------------------------------------------------------------------------- 1 | CXX_STD = CXX17 2 | PKG_CPPFLAGS = -I../inst/include/ 3 | -------------------------------------------------------------------------------- /src/Makevars.win: -------------------------------------------------------------------------------- 1 | CXX_STD = CXX17 2 | PKG_CPPFLAGS = -I../inst/include/ 3 | -------------------------------------------------------------------------------- /src/data.h: -------------------------------------------------------------------------------- 1 | #ifndef DATA_H 2 | #define DATA_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "model.h" 8 | 9 | template 10 | struct data{ 11 | data( 12 | Eigen::VectorXd y, 13 | Eigen::VectorXd trials, 14 | Eigen::MatrixXd X, 15 | Eigen::SparseMatrix Zt 16 | ) : 17 | y { y.cast() }, trials { trials.cast() }, X { X.cast() }, 18 | Zt { Zt.cast() } 19 | {} 20 | 21 | Vdual y; 22 | Vdual trials; 23 | Mdual X; 24 | SpMdual Zt; 25 | }; 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /src/parameters.h: -------------------------------------------------------------------------------- 1 | #ifndef PARAMETERS_H 2 | #define PARAMETERS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "model.h" 8 | 9 | //' @name parameters 10 | //' @title Structure for keeping track of parameters 11 | //' @description See the documentation of other functions, e.g., 12 | //' \code{marginal_likelihood}, for an explanation of what the different 13 | //' parameters represent. 14 | //' @field new Constructor, which takes parameters as arguments, and then 15 | //' if necessary converts them to the template type \code{T}. 16 | //' @noRd 17 | template 18 | struct parameters{ 19 | parameters( 20 | const Eigen::VectorXd& theta, 21 | const Eigen::VectorXd& beta, 22 | const Eigen::VectorXd& lambda, 23 | const Eigen::VectorXd& u, 24 | const std::vector& theta_mapping, 25 | const Eigen::VectorXi& lambda_mapping_X, 26 | const Rcpp::ListOf& lambda_mapping_Zt0, 27 | const Rcpp::ListOf& lambda_mapping_Zt_covs0, 28 | const Eigen::SparseMatrix& Lambdat, 29 | const Eigen::VectorXd& weights, 30 | const std::vector& weights_mapping, 31 | const Eigen::VectorXi& family_mapping, 32 | const int& maxit_conditional_modes, 33 | const double& lossvalue_tol, 34 | const int& n 35 | ) : 36 | theta { theta.cast() }, 37 | beta { beta.cast() }, 38 | lambda { lambda.cast() }, 39 | u { u.cast() }, 40 | theta_mapping { theta_mapping }, 41 | lambda_mapping_X { lambda_mapping_X }, 42 | Lambdat { Lambdat.cast() }, 43 | weights { weights.cast() }, 44 | weights_mapping { weights_mapping }, 45 | family_mapping { family_mapping }, 46 | maxit_conditional_modes { maxit_conditional_modes }, 47 | lossvalue_tol { lossvalue_tol }, 48 | n { n } 49 | { 50 | for(int i{}; i < lambda_mapping_Zt0.size(); i++){ 51 | lambda_mapping_Zt.push_back(Rcpp::as>(lambda_mapping_Zt0[i])); 52 | } 53 | for(int i{}; i < lambda_mapping_Zt_covs0.size(); i++){ 54 | lambda_mapping_Zt_covs.push_back(Rcpp::as>(lambda_mapping_Zt_covs0[i])); 55 | } 56 | 57 | WSqrt.diagonal() = Vdual::Constant(n, 1); 58 | } 59 | 60 | 61 | Vdual theta; 62 | Vdual beta; 63 | Vdual lambda; 64 | Vdual u; 65 | std::vector theta_mapping; 66 | Eigen::VectorXi lambda_mapping_X = {}; 67 | std::vector> lambda_mapping_Zt = {}; 68 | std::vector> lambda_mapping_Zt_covs = {}; 69 | Eigen::SparseMatrix Lambdat; 70 | Vdual weights; 71 | std::vector weights_mapping; 72 | Eigen::VectorXi family_mapping; 73 | Ddual WSqrt; 74 | int maxit_conditional_modes; 75 | double lossvalue_tol; 76 | int n; 77 | }; 78 | 79 | //' @name logLikObject 80 | //' @title Structure containing values to be returned to R 81 | //' @noRd 82 | template 83 | struct logLikObject { 84 | T logLikValue; 85 | Vdual V; 86 | Vdual u; 87 | Vdual phi; 88 | }; 89 | 90 | #endif 91 | 92 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(galamm) 3 | 4 | test_check("galamm") 5 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/galamm-glmm.md: -------------------------------------------------------------------------------- 1 | # Logistic GLMM with simple factor works 2 | 3 | Code 4 | summary(mod) 5 | Output 6 | GALAMM fit by maximum marginal likelihood. 7 | Formula: form 8 | Data: dat 9 | 10 | AIC BIC logLik deviance df.resid 11 | 315.3 353.8 -146.7 224.7 234 12 | 13 | Scaled residuals: 14 | Min 1Q Median 3Q Max 15 | -2.5366 -0.7186 0.4074 0.5952 1.5062 16 | 17 | Lambda: 18 | abil.sid SE 19 | lambda1 1.0000 . 20 | lambda2 1.0765 1.0012 21 | lambda3 0.8904 0.5977 22 | lambda4 0.7358 0.5887 23 | lambda5 1.2040 1.0143 24 | 25 | Random effects: 26 | Groups Name Variance Std.Dev. 27 | sid:school abil.sid 1.631 1.277 28 | school abil.sid 0.000 0.000 29 | Number of obs: 245, groups: sid:school, 49; school, 4 30 | 31 | Fixed effects: 32 | Estimate Std. Error z value Pr(>|z|) 33 | (Intercept) 0.6079 0.4118 1.4763 0.1399 34 | item2 0.9278 0.7036 1.3185 0.1873 35 | item3 -0.6684 0.4927 -1.3566 0.1749 36 | item4 0.3654 0.5292 0.6906 0.4898 37 | item5 0.3130 0.5966 0.5246 0.5999 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/galamm-heteroscedastic.md: -------------------------------------------------------------------------------- 1 | # Heteroscedastic model works 2 | 3 | Code 4 | print(summary(mod), digits = 3) 5 | Output 6 | GALAMM fit by maximum marginal likelihood. 7 | Formula: y ~ x + (1 | id) 8 | Data: hsced 9 | Weights: ~(1 | item) 10 | 11 | AIC BIC logLik deviance df.resid 12 | 4126.3 4151.7 -2058.1 4116.3 1195 13 | 14 | Scaled residuals: 15 | Min 1Q Median 3Q Max 16 | -5.654 -0.711 0.029 0.683 4.326 17 | 18 | Random effects: 19 | Groups Name Variance Std.Dev. 20 | id (Intercept) 0.988 0.994 21 | Residual 0.960 0.980 22 | Number of obs: 1200, groups: id, 200 23 | 24 | Variance function: 25 | 1 2 26 | 1.00 1.99 27 | 28 | Fixed effects: 29 | Estimate Std. Error t value Pr(>|t|) 30 | (Intercept) 0.129 0.0992 1.30 1.94e-01 31 | x 0.706 0.1213 5.82 5.82e-09 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/galamm-latent-covariates-interaction.md: -------------------------------------------------------------------------------- 1 | # Interaction between latent and observed covariates works 2 | 3 | Code 4 | print(summary(mod), digits = 2) 5 | Output 6 | GALAMM fit by maximum marginal likelihood. 7 | Formula: formula 8 | Data: data 9 | 10 | AIC BIC logLik deviance df.resid 11 | 138.3 177.9 -60.2 120.3 591 12 | 13 | Scaled residuals: 14 | Min 1Q Median 3Q Max 15 | -2.20 -0.53 -0.03 0.51 3.50 16 | 17 | Lambda: 18 | loading SE 19 | lambda1 1.00 . 20 | lambda2 1.30 0.013 21 | lambda3 -0.32 0.016 22 | lambda4_x 0.23 0.029 23 | 24 | Random effects: 25 | Groups Name Variance Std.Dev. 26 | id loading 0.982 0.99 27 | Residual 0.012 0.11 28 | Number of obs: 600, groups: id, 200 29 | 30 | Fixed effects: 31 | Estimate Std. Error t value Pr(>|t|) 32 | (Intercept) -0.0106 0.070 -0.150 8.8e-01 33 | typemeasurement2 -0.0022 0.024 -0.091 9.3e-01 34 | typeresponse 0.0340 0.094 0.361 7.2e-01 35 | x:response 0.4625 0.033 14.016 1.3e-44 36 | 37 | 38 | 39 | --- 40 | 41 | Code 42 | print(summary(modq), digits = 2) 43 | Output 44 | GALAMM fit by maximum marginal likelihood. 45 | Formula: formula 46 | Data: data 47 | 48 | AIC BIC logLik deviance df.resid 49 | 140.3 184.2 -60.1 120.3 590 50 | 51 | Scaled residuals: 52 | Min 1Q Median 3Q Max 53 | -2.20 -0.52 -0.02 0.52 3.50 54 | 55 | Lambda: 56 | loading SE 57 | lambda1 1.000 . 58 | lambda2 1.303 0.013 59 | lambda3 -0.314 0.024 60 | lambda4_x 0.209 0.113 61 | lambda5_I(x^2) 0.025 0.111 62 | 63 | Random effects: 64 | Groups Name Variance Std.Dev. 65 | id loading 0.982 0.99 66 | Residual 0.012 0.11 67 | Number of obs: 600, groups: id, 200 68 | 69 | Fixed effects: 70 | Estimate Std. Error t value Pr(>|t|) 71 | (Intercept) -0.0099 0.071 -0.141 8.9e-01 72 | typemeasurement2 -0.0020 0.024 -0.083 9.3e-01 73 | typeresponse 0.0333 0.094 0.353 7.2e-01 74 | x:response 0.4622 0.033 13.984 2.0e-44 75 | 76 | 77 | 78 | --- 79 | 80 | Code 81 | print(anova(modq, mod), digits = 3) 82 | Output 83 | Data: data 84 | Models: 85 | mod: formula 86 | modq: formula 87 | npar AIC BIC logLik deviance Chisq Df Pr(>Chisq) 88 | mod 9 138 178 -60.2 120 89 | modq 10 140 184 -60.1 120 0.05 1 0.83 90 | 91 | # Crossed latent-observed interaction models work 92 | 93 | Code 94 | print(summary(mod), digits = 2) 95 | Output 96 | GALAMM fit by maximum marginal likelihood. 97 | Formula: formula 98 | Data: data 99 | 100 | AIC BIC logLik deviance df.resid 101 | 63.2 103.0 -21.6 43.2 386 102 | 103 | Scaled residuals: 104 | Min 1Q Median 3Q Max 105 | -3.27 -0.52 -0.04 0.50 3.80 106 | 107 | Lambda: 108 | loading SE 109 | lambda1 1.00 . 110 | lambda2 1.31 0.024 111 | lambda3 -0.37 0.023 112 | lambda4_x 0.31 0.040 113 | 114 | Random effects: 115 | Groups Name Variance Std.Dev. 116 | id loading 0.904 0.95 117 | id.1 response 0.000 0.00 118 | Residual 0.019 0.14 119 | Number of obs: 396, groups: id, 99 120 | 121 | Fixed effects: 122 | Estimate Std. Error t value Pr(>|t|) 123 | (Intercept) -0.033 0.097 -0.34 7.3e-01 124 | typemeasurement2 -0.012 0.036 -0.35 7.3e-01 125 | typeresponse 0.073 0.134 0.55 5.8e-01 126 | x:response 0.432 0.048 8.98 2.7e-19 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/galamm-mixed-resp.md: -------------------------------------------------------------------------------- 1 | # Covariate measurement error model works 2 | 3 | Code 4 | anova(mod, mod0) 5 | Output 6 | Data: diet 7 | Models: 8 | mod0: formula0 9 | mod: formula 10 | npar AIC BIC logLik deviance Chisq Df Pr(>Chisq) 11 | mod0 9 2764.0 2805.5 -1373.0 2002.9 12 | mod 12 2768.3 2823.6 -1372.2 2002.9 1.7058 3 0.6357 13 | 14 | # Mixed response and heteroscedastic error works 15 | 16 | Code 17 | print(summary(mod), digits = 2) 18 | Output 19 | GALAMM fit by maximum marginal likelihood. 20 | Formula: y ~ x + (1 | id) 21 | Data: mresp_hsced 22 | Weights: ~(0 + isgauss | grp) 23 | 24 | AIC BIC logLik deviance df.resid 25 | 12356.9 12388.3 -6173.4 31426.4 3995 26 | 27 | Random effects: 28 | Groups Name Variance Std.Dev. 29 | id (Intercept) 0 0 30 | Number of obs: 4000, groups: id, 1000 31 | 32 | Variance function: 33 | a b 34 | 1.000 0.078 35 | 36 | Fixed effects: 37 | Estimate Std. Error z value Pr(>|z|) 38 | (Intercept) 0.015 0.063 0.24 8.1e-01 39 | x 0.996 0.112 8.93 4.4e-19 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/galamm-setup.md: -------------------------------------------------------------------------------- 1 | # multiple factors and factors in fixed effects are allowed 2 | 3 | Code 4 | print(summary(kyps.model), digits = 2) 5 | Output 6 | GALAMM fit by maximum marginal likelihood. 7 | Formula: esteem ~ as.factor(time) + (0 + hs | hid) + (0 + ms | mid) 8 | Data: KYPSsim 9 | Control: 10 | galamm_control(optim_control = list(maxit = 1), maxit_conditional_modes = 1) 11 | 12 | AIC BIC logLik deviance df.resid 13 | 24141.8 24222.7 -12059.9 24119.8 11483 14 | 15 | Scaled residuals: 16 | Min 1Q Median 3Q Max 17 | -3.46 -0.57 0.03 0.64 3.52 18 | 19 | Lambda: 20 | ms SE hs SE 21 | lambda1 1.0 . . . 22 | lambda2 1.1 0.21 . . 23 | lambda3 1.0 0.40 1.00 . 24 | lambda4 1.0 0.43 0.98 0.056 25 | 26 | Random effects: 27 | Groups Name Variance Std.Dev. 28 | hid hs 0.39 0.63 29 | mid ms 0.58 0.76 30 | Residual 0.40 0.63 31 | Number of obs: 11494, groups: hid, 860; mid, 104 32 | 33 | Fixed effects: 34 | Estimate Std. Error t value Pr(>|t|) 35 | (Intercept) 0.071 0.0028 25.457 5.9e-143 36 | as.factor(time)2 0.030 0.6255 0.048 9.6e-01 37 | as.factor(time)3 0.013 1.1704 0.011 9.9e-01 38 | as.factor(time)4 0.014 1.2638 0.011 9.9e-01 39 | 40 | 41 | 42 | --- 43 | 44 | Code 45 | print(summary(kyps.model), digits = 2) 46 | Output 47 | GALAMM fit by maximum marginal likelihood. 48 | Formula: esteem ~ 1 + ms:time2 + (1 | sid) 49 | Data: subset(KYPSsim, time %in% c(1, 2)) 50 | Control: 51 | galamm_control(optim_control = list(maxit = 1), maxit_conditional_modes = 1) 52 | 53 | AIC BIC logLik deviance df.resid 54 | 17612.0 17645.3 -8801.0 17602.0 5749 55 | 56 | Scaled residuals: 57 | Min 1Q Median 3Q Max 58 | -2.18 -0.36 0.21 0.77 2.51 59 | 60 | Lambda: 61 | ms SE 62 | lambda1 1.0 . 63 | lambda2 1.1 0.016 64 | 65 | Random effects: 66 | Groups Name Variance Std.Dev. 67 | sid (Intercept) 2.02 1.42 68 | Residual 0.35 0.59 69 | Number of obs: 5754, groups: sid, 2924 70 | 71 | Fixed effects: 72 | Estimate Std. Error t value Pr(>|t|) 73 | (Intercept) 1.69 0.021 81 0 74 | ms:time2 0.75 0.011 67 0 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /tests/testthat/test-galamm-heteroscedastic.R: -------------------------------------------------------------------------------- 1 | test_that("Heteroscedastic model works", { 2 | mod <- galamm( 3 | formula = y ~ x + (1 | id), 4 | weights = ~ (1 | item), 5 | data = hsced 6 | ) 7 | 8 | expect_snapshot(print(summary(mod), digits = 3)) 9 | expect_equal(mod$model$loglik, -2058.14021326104) 10 | expect_equal( 11 | summary(mod)$AICtab, 12 | c( 13 | AIC = 4126.28042652208, BIC = 4151.73081070096, 14 | logLik = -2058.14021326104, 15 | deviance = 4116.28042652208, df.resid = 1195 16 | ) 17 | ) 18 | expect_equal(summary(mod)$Lambda, NULL) 19 | 20 | expect_equal( 21 | residuals(mod)[c(4, 8, 11)], 22 | c(0.879617156429014, -1.83921105781445, 0.769190482966503) 23 | ) 24 | 25 | expect_equal(vcov(mod, parm = "weights"), 26 | structure(0.00245961267414418, dim = c(1L, 1L)), 27 | tolerance = 1e-4 28 | ) 29 | 30 | expect_equal(vcov(mod, parm = 1L), 31 | structure(0.00543386086733993, dim = c(1L, 1L)), 32 | tolerance = 1e-4 33 | ) 34 | 35 | expect_error(vcov(mod, parm = 5L), "out of bounds") 36 | expect_error(vcov(mod, parm = "phi"), "Parameter not found") 37 | 38 | expect_error( 39 | galamm( 40 | formula = y ~ x + (1 | id), 41 | weights = list(~ (1 | item)), 42 | data = hsced 43 | ), 44 | "weights must be a formula" 45 | ) 46 | 47 | 48 | # Now use initial values 49 | mod_start <- galamm( 50 | formula = y ~ x + (1 | id), 51 | weights = ~ (1 | item), 52 | data = hsced, 53 | start = list(beta = c(.13, .70), theta = 1.01, weights = .501) 54 | ) 55 | 56 | expect_equal( 57 | mod_start$parameters$parameter_estimates, 58 | mod$parameters$parameter_estimates, 59 | tolerance = .01 60 | ) 61 | }) 62 | -------------------------------------------------------------------------------- /tests/testthat/test-galamm-latent-covariates-interaction.R: -------------------------------------------------------------------------------- 1 | test_that("Interaction between latent and observed covariates works", { 2 | formula <- y ~ type + x:response + (0 + loading | id) 3 | data <- latent_covariates 4 | load.var <- "type" 5 | lambda <- matrix(c(1, NA, NA), ncol = 1) 6 | factor <- "loading" 7 | factor_interactions <- list(~1, ~1, ~x) 8 | 9 | mod <- galamm( 10 | formula = formula, 11 | data = data, 12 | load.var = load.var, 13 | lambda = lambda, 14 | factor = factor, 15 | factor_interactions = factor_interactions 16 | ) 17 | 18 | expect_snapshot(print(summary(mod), digits = 2)) 19 | 20 | mod0a <- galamm( 21 | formula = formula, 22 | data = data, 23 | load.var = load.var, 24 | lambda = lambda, 25 | factor = factor, 26 | factor_interactions = list(~1, ~1, ~1) 27 | ) 28 | 29 | mod0b <- galamm( 30 | formula = formula, 31 | data = data, 32 | load.var = load.var, 33 | lambda = lambda, 34 | factor = factor 35 | ) 36 | 37 | expect_equal(deviance(mod0a), deviance(mod0b)) 38 | 39 | modq <- galamm( 40 | formula = formula, 41 | data = data, 42 | load.var = load.var, 43 | lambda = lambda, 44 | factor = factor, 45 | factor_interactions = list(~1, ~1, ~ x + I(x^2)) 46 | ) 47 | 48 | expect_snapshot(print(summary(modq), digits = 2)) 49 | expect_snapshot(print(anova(modq, mod), digits = 3)) 50 | }) 51 | 52 | test_that("Crossed latent-observed interaction models work", { 53 | formula <- y ~ type + x:response + (0 + loading | id) + (0 + response | id) 54 | data <- subset(latent_covariates_long, id < 100) 55 | load.var <- "type" 56 | lambda <- matrix(c(1, NA, NA), ncol = 1) 57 | factor <- "loading" 58 | factor_interactions <- list(~1, ~1, ~x) 59 | 60 | mod <- galamm( 61 | formula = formula, 62 | data = data, 63 | load.var = load.var, 64 | lambda = lambda, 65 | factor = factor, 66 | factor_interactions = factor_interactions 67 | ) 68 | 69 | expect_snapshot(print(summary(mod), digits = 2)) 70 | }) 71 | 72 | 73 | test_that("Latent-observed interaction with smooths", { 74 | data <- latent_covariates 75 | data$m1 <- as.numeric(data$type == "measurement1") 76 | data$m2 <- as.numeric(data$type == "measurement2") 77 | formula <- y ~ 0 + m1 + m2 + s(x, k = 4, by = response) + 78 | (0 + loading | id) 79 | 80 | load.var <- "type" 81 | lambda <- matrix(c(1, NA, NA), ncol = 1) 82 | factor <- "loading" 83 | factor_interactions <- list(~1, ~1, ~x) 84 | 85 | mod <- galamm( 86 | formula = formula, 87 | data = data, 88 | load.var = load.var, 89 | lambda = lambda, 90 | factor = factor, 91 | factor_interactions = factor_interactions 92 | ) 93 | 94 | expect_equal(deviance(mod), 120.311, tolerance = 1e-3) 95 | expect_equal(mod$gam$edf, 96 | c( 97 | m1 = 0.999999999999793, m2 = 1.00000000000022, 98 | `s(x):response.1` = 1.76038497918713e-10, 99 | `s(x):response.2` = 2.52273958510005e-11, 100 | `s(x):response.3` = 1, `s(x):response.4` = 1 101 | ), 102 | tolerance = .1 103 | ) 104 | 105 | data <- latent_covariates_long 106 | formula <- y ~ s(x, by = response) + (0 + loading | id) + (0 + response | id) 107 | 108 | mod <- galamm( 109 | formula = formula, 110 | data = data, 111 | load.var = load.var, 112 | lambda = lambda, 113 | factor = factor, 114 | factor_interactions = factor_interactions 115 | ) 116 | 117 | expect_equal(deviance(mod), 130.6347, tolerance = 1e-3) 118 | }) 119 | -------------------------------------------------------------------------------- /tests/testthat/test-misc.R: -------------------------------------------------------------------------------- 1 | test_that("skip_extended works", { 2 | current_value <- Sys.getenv("GALAMM_EXTENDED_TESTS") 3 | Sys.setenv(GALAMM_EXTENDED_TESTS = "true") 4 | expect_condition(skip_extended(), NA, class = "skip") 5 | Sys.setenv(GALAMM_EXTENDED_TESTS = "") 6 | expect_condition(skip_extended(), class = "skip") 7 | Sys.setenv(GALAMM_EXTENDED_TESTS = current_value) 8 | }) 9 | -------------------------------------------------------------------------------- /update_autodiff.sh: -------------------------------------------------------------------------------- 1 | # 2 | rm -r inst/include/autodiff 3 | mkdir tmp 4 | cd tmp 5 | git clone https://github.com/autodiff/autodiff.git 6 | 7 | mkdir ../inst/include/autodiff/ 8 | cp -r autodiff/autodiff/common ../inst/include/autodiff 9 | cp -r autodiff/autodiff/forward ../inst/include/autodiff 10 | cp -r autodiff/autodiff/reverse ../inst/include/autodiff 11 | 12 | cd .. 13 | rm -rf tmp/ 14 | 15 | R CMD BATCH insert_sparse_autodiff.R 16 | rm insert_sparse_autodiff.Rout 17 | -------------------------------------------------------------------------------- /vignettes-raw/lmm_heteroscedastic.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Heteroscedastic Linear Mixed Models" 3 | output: 4 | rmarkdown::html_vignette: 5 | fig_width: 6 6 | fig_height: 4 7 | bibliography: ../inst/REFERENCES.bib 8 | link-citations: yes 9 | vignette: > 10 | %\VignetteIndexEntry{Heteroscedastic Linear Mixed Models} 11 | %\VignetteEngine{knitr::rmarkdown} 12 | %\VignetteEncoding{UTF-8} 13 | --- 14 | 15 | ```{r, include = FALSE} 16 | knitr::opts_chunk$set( 17 | collapse = TRUE, 18 | comment = "#>", 19 | fig.path = "", 20 | error = FALSE 21 | ) 22 | ``` 23 | 24 | ```{r setup} 25 | library(galamm) 26 | ``` 27 | 28 | At the moment, galamm supports group-wise heteroscedasticity in Gaussian response models. Referring to the model formulation outlined in the [introductory vignette](https://lcbc-uio.github.io/galamm/articles/galamm.html), the response model and nonlinear predictor can be easily combined in this particular case, to give 29 | 30 | $$ 31 | y_{i} = \sum_{s=1}^{S} f_{s}\left(\mathbf{x}_{i}\right) + \sum_{l=2}^{L}\sum_{m=1}^{M_{l}} \eta_{m}^{(l)} \mathbf{z}^{(l)}_{im}{}^{'}\boldsymbol{\lambda}_{m}^{(l)} + \epsilon_{g(i)}, 32 | $$ 33 | 34 | where subscript $i$ refers to the $i$th elementary unit of observation, i.e., the $i$th row in the dataframe. $g(i)$ refers to the group to which the $i$th observation belongs, with each grouping having a separately estimated residual variance, $\epsilon_{g} \sim N(0, \sigma_{g}^{2})$. 35 | 36 | In the future, we plan to also support other types of residual terms, including autocorrelation and residuals that depend on continuous variables. Such features are currently supported by the R packages [nlme](https://cran.r-project.org/package=nlme) [@pinheiroMixedEffectsModelsSPLUS2000], [mgcv](https://cran.r-project.org/package=mgcv) [@woodGeneralizedAdditiveModels2017], and [gamlss](https://cran.r-project.org/package=gamlss) [@rigbyGeneralizedAdditiveModels2005], however, of these only nlme provides computationally efficient estimation of mixed effects models with a large number of grouping levels, and only with strictly nested groups. If you are aware of other packages implementing such functionality, please [let us know](https://github.com/LCBC-UiO/galamm/issues). 37 | 38 | ## Group-Wise Heteroscedasticity 39 | 40 | The package includes a simulated dataset `hsced`, in which the residual variance varies between items. 41 | 42 | ```{r} 43 | head(hsced) 44 | ``` 45 | 46 | We specify the error structure using an additional formula object, `~ (1 | item)`, specifying that a different constraint term should be included per item. 47 | 48 | ```{r} 49 | mod <- galamm( 50 | formula = y ~ x + (1 | id), 51 | weights = ~ (1 | item), 52 | data = hsced 53 | ) 54 | ``` 55 | 56 | The output shows that for item 2, the residual variance is twice that of item 1. 57 | 58 | ```{r} 59 | summary(mod) 60 | ``` 61 | 62 | We can confirm that the lme function from the nlme package gives the same result. It reports the multiplies on the standard deviation scale, so since $1.412369^2 = 1.995$, the results are identical. 63 | 64 | ```{r} 65 | library(nlme) 66 | mod_nlme <- lme(y ~ x, 67 | data = hsced, random = list(id = ~1), 68 | weights = varIdent(form = ~ 1 | item), method = "ML" 69 | ) 70 | summary(mod_nlme) 71 | ``` 72 | 73 | 74 | The diagnostic plot also looks good. 75 | 76 | ```{r, lmm_heteroscedastic_diagnostic, fig.cap="Diagnostic plot for heteroscedastic model."} 77 | plot(mod) 78 | ``` 79 | 80 | We can compare the model to one with homoscedastic residuals. 81 | 82 | ```{r} 83 | mod0 <- galamm( 84 | formula = y ~ x + (1 | id), 85 | data = hsced 86 | ) 87 | ``` 88 | 89 | 90 | Reassuringly, the correct model is chosen in this simple simulated case. 91 | 92 | ```{r} 93 | anova(mod, mod0) 94 | ``` 95 | 96 | 97 | 98 | # References 99 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/glmm_factor_binomial_diagnostic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/glmm_factor_binomial_diagnostic-1.png -------------------------------------------------------------------------------- /vignettes/glmm_factor_poisson_diagnostic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/glmm_factor_poisson_diagnostic-1.png -------------------------------------------------------------------------------- /vignettes/glmm_factor_poisson_diagnostic_lme4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/glmm_factor_poisson_diagnostic_lme4-1.png -------------------------------------------------------------------------------- /vignettes/latent-observed-smooth-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/latent-observed-smooth-1.png -------------------------------------------------------------------------------- /vignettes/lmm_factor_diagnostic_plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/lmm_factor_diagnostic_plot-1.png -------------------------------------------------------------------------------- /vignettes/lmm_heteroscedastic_diagnostic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/lmm_heteroscedastic_diagnostic-1.png -------------------------------------------------------------------------------- /vignettes/scaling-glmm-plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/scaling-glmm-plot-1.png -------------------------------------------------------------------------------- /vignettes/scaling-hsced-plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/scaling-hsced-plot-1.png -------------------------------------------------------------------------------- /vignettes/scaling-lmm-plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/scaling-lmm-plot-1.png -------------------------------------------------------------------------------- /vignettes/scaling-semiparametric-binomial-plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/scaling-semiparametric-binomial-plot-1.png -------------------------------------------------------------------------------- /vignettes/scaling-semiparametric-gaussian-plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/scaling-semiparametric-gaussian-plot-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gamm-binomial-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gamm-binomial-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gamm4-binomial-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gamm4-binomial-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-by-factor1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-by-factor1-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-by-factor2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-by-factor2-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-factor-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-factor-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-gamm-diagnostic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-gamm-diagnostic-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-gamm-smooth1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-gamm-smooth1-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-gamm-smooth2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-gamm-smooth2-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-gamm-smooth2-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-gamm-smooth2-2.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-gamm4-diagnostic-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-gamm4-diagnostic-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-gaussian-gamm4-smooth-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-gaussian-gamm4-smooth-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-mixed-by-factor1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-mixed-by-factor1-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-mixed-by-factor2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-mixed-by-factor2-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-mixedresponse-smooths1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-mixedresponse-smooths1-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-mixedresponse-smooths2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-mixedresponse-smooths2-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-mixedresponse-smooths3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-mixedresponse-smooths3-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-multivariate-gaussian-smooth1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-multivariate-gaussian-smooth1-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-multivariate-gaussian-smooth2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-multivariate-gaussian-smooth2-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-multivariate-spaghetti-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-multivariate-spaghetti-1.png -------------------------------------------------------------------------------- /vignettes/semiparametric-spaghetti-plot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LCBC-UiO/galamm/aa31823b72c351f983f36d1d924aa8628051114e/vignettes/semiparametric-spaghetti-plot-1.png --------------------------------------------------------------------------------