From fef3049eb07246132c37a15bbe74f92e45758020 Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Sat, 8 Sep 2018 19:38:41 +0200 Subject: [PATCH 01/17] fix bppd in dprime --- R/dprime.R | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/R/dprime.R b/R/dprime.R index ea976f4..f012597 100644 --- a/R/dprime.R +++ b/R/dprime.R @@ -12,13 +12,13 @@ #' #' @return Calculates the d', the beta, the A' and the B''D based on the signal detection theory (SRT). See Pallier (2002) for the algorithms. #' -#' Returns a list containing 4 objects: +#' Returns a list containing the following indices: #' \itemize{ #' \item{\strong{dprime (d')}: }{The sensitivity. Reflects the distance between the two distributions: signal, and signal+noise and corresponds to the Z value of the hit-rate minus that of the false-alarm rate.} #' \item{\strong{beta}: }{The bias (criterion). The value for beta is the ratio of the normal density functions at the criterion of the Z values used in the computation of d'. This reflects an observer's bias to say 'yes' or 'no' with the unbiased observer having a value around 1.0. As the bias to say 'yes' increases (liberal), resulting in a higher hit-rate and false-alarm-rate, beta approaches 0.0. As the bias to say 'no' increases (conservative), resulting in a lower hit-rate and false-alarm rate, beta increases over 1.0 on an open-ended scale.} +#' \item{\strong{c}: }{Another index of bias. the number of standard deviations from the midpoint between these two distributions, i.e., a measure on a continuum from "conservative" to "liberal".} #' \item{\strong{aprime (A')}: }{Non-parametric estimate of discriminability. An A' near 1.0 indicates good discriminability, while a value near 0.5 means chance performance.} #' \item{\strong{bppd (B''D)}: }{Non-parametric estimate of bias. A B''D equal to 0.0 indicates no bias, positive numbers represent conservative bias (i.e., a tendency to answer 'no'), negative numbers represent liberal bias (i.e. a tendency to answer 'yes'). The maximum absolute value is 1.0.} -#' \item{\strong{c}: }{Another index of bias. the number of standard deviations from the midpoint between these two distributions, i.e., a measure on a continuum from "conservative" to "liberal".} #' } #' #' @@ -119,7 +119,11 @@ dprime <- function(n_hit, n_fa, n_miss=NULL, n_cr=NULL, n_targets=NULL, n_distra aprime <- a # bppd - bppd <- ((1 - hit_rate) * (1 - fa_rate) - hit_rate * fa_rate) / ((1 - hit_rate) * (1 - fa_rate) + hit_rate * fa_rate) + if(hit_rate >= fa_rate){ + bppd <- (hit_rate * (1 - hit_rate) - fa_rate * (1 - fa_rate)) /(hit_rate * (1 - hit_rate) + fa_rate * (1 - fa_rate)) + } else{ + bppd <- (fa_rate * (1 - fa_rate) - hit_rate * (1 - hit_rate)) / (fa_rate * (1 - fa_rate) + hit_rate * (1 - hit_rate)) + } return(list(dprime = dprime, beta = beta, aprime = aprime, bppd = bppd, c = c)) From 8d963378bb96899a3a8aed849278f87eedeed18d Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Thu, 13 Sep 2018 10:48:45 +0200 Subject: [PATCH 02/17] fix for CRAN --- DESCRIPTION | 4 ++-- R/dprime.R | 9 ++++----- man/dprime.Rd | 4 ++-- tests/testthat/test-dprime.R | 3 +-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index e3ea8a0..c1fee0f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: psycho Type: Package Title: Efficient and Publishing-Oriented Workflow for Psychological Science -Version: 0.3.6 +Version: 0.3.7 Authors@R: c( person("Dominique", "Makowski", @@ -30,7 +30,7 @@ Encoding: UTF-8 LazyData: true RoxygenNote: 6.1.0 Depends: - R (>= 3.4.0) + R (>= 3.5.0) Imports: methods, dplyr, diff --git a/R/dprime.R b/R/dprime.R index f012597..70b41f9 100644 --- a/R/dprime.R +++ b/R/dprime.R @@ -119,11 +119,10 @@ dprime <- function(n_hit, n_fa, n_miss=NULL, n_cr=NULL, n_targets=NULL, n_distra aprime <- a # bppd - if(hit_rate >= fa_rate){ - bppd <- (hit_rate * (1 - hit_rate) - fa_rate * (1 - fa_rate)) /(hit_rate * (1 - hit_rate) + fa_rate * (1 - fa_rate)) - } else{ - bppd <- (fa_rate * (1 - fa_rate) - hit_rate * (1 - hit_rate)) / (fa_rate * (1 - fa_rate) + hit_rate * (1 - hit_rate)) - } + bppd <- (hit_rate * (1 - hit_rate) - fa_rate * (1 - fa_rate)) / (hit_rate * (1 - hit_rate) + fa_rate * (1 - fa_rate)) + bppd_b <- (fa_rate * (1 - fa_rate) - hit_rate * (1 - hit_rate)) / (fa_rate * (1 - fa_rate) + hit_rate * (1 - hit_rate)) + bppd[fa_rate > hit_rate] <- bppd_b[fa_rate > hit_rate] + return(list(dprime = dprime, beta = beta, aprime = aprime, bppd = bppd, c = c)) diff --git a/man/dprime.Rd b/man/dprime.Rd index b559b6e..87b179f 100644 --- a/man/dprime.Rd +++ b/man/dprime.Rd @@ -25,13 +25,13 @@ dprime(n_hit, n_fa, n_miss = NULL, n_cr = NULL, n_targets = NULL, \value{ Calculates the d', the beta, the A' and the B''D based on the signal detection theory (SRT). See Pallier (2002) for the algorithms. -Returns a list containing 4 objects: +Returns a list containing the following indices: \itemize{ \item{\strong{dprime (d')}: }{The sensitivity. Reflects the distance between the two distributions: signal, and signal+noise and corresponds to the Z value of the hit-rate minus that of the false-alarm rate.} \item{\strong{beta}: }{The bias (criterion). The value for beta is the ratio of the normal density functions at the criterion of the Z values used in the computation of d'. This reflects an observer's bias to say 'yes' or 'no' with the unbiased observer having a value around 1.0. As the bias to say 'yes' increases (liberal), resulting in a higher hit-rate and false-alarm-rate, beta approaches 0.0. As the bias to say 'no' increases (conservative), resulting in a lower hit-rate and false-alarm rate, beta increases over 1.0 on an open-ended scale.} + \item{\strong{c}: }{Another index of bias. the number of standard deviations from the midpoint between these two distributions, i.e., a measure on a continuum from "conservative" to "liberal".} \item{\strong{aprime (A')}: }{Non-parametric estimate of discriminability. An A' near 1.0 indicates good discriminability, while a value near 0.5 means chance performance.} \item{\strong{bppd (B''D)}: }{Non-parametric estimate of bias. A B''D equal to 0.0 indicates no bias, positive numbers represent conservative bias (i.e., a tendency to answer 'no'), negative numbers represent liberal bias (i.e. a tendency to answer 'yes'). The maximum absolute value is 1.0.} - \item{\strong{c}: }{Another index of bias. the number of standard deviations from the midpoint between these two distributions, i.e., a measure on a continuum from "conservative" to "liberal".} } diff --git a/tests/testthat/test-dprime.R b/tests/testthat/test-dprime.R index eee185e..cd952a3 100644 --- a/tests/testthat/test-dprime.R +++ b/tests/testthat/test-dprime.R @@ -2,8 +2,7 @@ context("dprime") test_that("Correct Value", { testthat::expect_equal(dprime(9, 2, 1, 7)$dprime, 1.65, tolerance = 0.1) - testthat::expect_equal(dprime(9, 0, 0, 0)$dprime, 1.74, tolerance = 0.1) - testthat::expect_equal(dprime(0, 0, 10, 0)$dprime, -1.28, tolerance = 0.1) + testthat::expect_equal(dprime(1, 9, 1, 0)$dprime, -1.49, tolerance = 0.1) df <- data.frame( Participant = c("A", "B", "C"), From af8cc93d3973b811bcb0157158eed29bf1ed6922 Mon Sep 17 00:00:00 2001 From: NAJBERG Hugo Date: Thu, 13 Sep 2018 13:57:22 +0200 Subject: [PATCH 03/17] See issue #90 #90 --- R/find_best_model.lmerModLmerTest.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/find_best_model.lmerModLmerTest.R b/R/find_best_model.lmerModLmerTest.R index ca52579..4d9cc53 100644 --- a/R/find_best_model.lmerModLmerTest.R +++ b/R/find_best_model.lmerModLmerTest.R @@ -54,6 +54,8 @@ find_best_model.lmerModLmerTest <- function(fit, interaction=TRUE, fixed=NULL, . # Model comparison comparison <- as.data.frame(do.call("anova", models)) + # Reordering the rows before implementing the combinations + comparison <- comparison[ order((row.names(comparison)),] comparison$formula <- combinations # Re-displaying warning messages From 8cec78af9acc59be489b5479104c8e6f4f5a6c9d Mon Sep 17 00:00:00 2001 From: NAJBERG Hugo Date: Fri, 14 Sep 2018 16:14:32 +0200 Subject: [PATCH 04/17] See issue #92 Better sorting to integrate the models' formula --- R/find_best_model.lmerModLmerTest.R | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/R/find_best_model.lmerModLmerTest.R b/R/find_best_model.lmerModLmerTest.R index 4d9cc53..28e0743 100644 --- a/R/find_best_model.lmerModLmerTest.R +++ b/R/find_best_model.lmerModLmerTest.R @@ -54,14 +54,22 @@ find_best_model.lmerModLmerTest <- function(fit, interaction=TRUE, fixed=NULL, . # Model comparison comparison <- as.data.frame(do.call("anova", models)) - # Reordering the rows before implementing the combinations - comparison <- comparison[ order((row.names(comparison)),] - comparison$formula <- combinations - + # Re-displaying warning messages options(warn = 0) + # Creating row names to the combinations array equivalent to the comparison data frame + combinations <- as.data.frame(combinations,row.names = paste0("MODEL", seq(1,length(combinations)))) + + # Reordering the rows in the same way for both combinations and comparison before implementing the formulas + comparison <- comparison[ order(row.names(comparison)),] + comparison$formula <- combinations[order(row.names(combinations)),] + + # Sorting the data frame by the AIC then BIC + comparison <- comparison[order(comparison$AIC,comparison$BIC),] + + # Best model by criterion best_aic <- dplyr::arrange_(comparison, "AIC") %>% dplyr::select_("formula") %>% From def202ab1f3cb88d63bba99127de9d9772e8d219 Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Thu, 20 Sep 2018 12:53:22 +0200 Subject: [PATCH 05/17] version bump --- DESCRIPTION | 2 +- docs/_posts/preparation/package_downloads.Rmd | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index c1fee0f..4485cea 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: psycho Type: Package Title: Efficient and Publishing-Oriented Workflow for Psychological Science -Version: 0.3.7 +Version: 0.3.8 Authors@R: c( person("Dominique", "Makowski", diff --git a/docs/_posts/preparation/package_downloads.Rmd b/docs/_posts/preparation/package_downloads.Rmd index ce5cc9a..efcb544 100644 --- a/docs/_posts/preparation/package_downloads.Rmd +++ b/docs/_posts/preparation/package_downloads.Rmd @@ -93,11 +93,12 @@ events <- left_join(events, data, by="date") library(rstanarm) library(psycho) -fit <- rstanarm::stan_glm(count~poly(day_num, 5), data=data) +fit <- rstanarm::stan_glm(count~poly(day_num, 5), data=data, algorithm="meanfield") # fit <- glm(count~poly(day_num, 5), data=data) psycho::get_predicted(fit, data) %>% ggplot(aes(x=date, group=1)) + + geom_hline(yintercept=0) + geom_line(aes(y=count), size=1) + geom_line(aes(y=count_Median), size=1, colour="blue") + geom_vline(data=events, aes(xintercept = date), colour=events$color, size=1) + From 77dbd3340338ab89694ba144164c346ec6afe5a4 Mon Sep 17 00:00:00 2001 From: Tobias Benz Date: Thu, 20 Sep 2018 15:18:33 +0200 Subject: [PATCH 06/17] Added ROPE to get_contrsts ROPE added as argument --- R/get_contrasts.stanreg.R | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/R/get_contrasts.stanreg.R b/R/get_contrasts.stanreg.R index 90bafdf..6b3bf4e 100644 --- a/R/get_contrasts.stanreg.R +++ b/R/get_contrasts.stanreg.R @@ -32,7 +32,7 @@ #' @importFrom stats confint mad #' #' @export -get_contrasts.stanreg <- function(fit, formula, prob=0.9, ...) { +get_contrasts.stanreg <- function(fit, formula, prob = 0.9, ROPE = FALSE, ROPE_bounds = NULL, ...) { formula <- as.formula(paste0("~", formula)) @@ -75,6 +75,33 @@ get_contrasts.stanreg <- function(fit, formula, prob=0.9, ...) { contrasts <- data.frame() + if (ROPE == TRUE) { + if (!is.null(ROPE_bounds)) { + for (name in names(contrasts_posterior)) { + var <- contrasts_posterior[[name]] + + CI_values <- HDI(var, prob = prob) + CI_values <- c(CI_values$values$HDImin, CI_values$values$HDImax) + + var <- data.frame( + Contrast = stringr::str_remove(name, "contrast "), + Median = median(var), + MAD = mad(var), + CI_lower = CI_values[seq(1, length(CI_values), 2)], + CI_higher = CI_values[seq(2, length(CI_values), 2)], + MPE = mpe(var)$MPE, + ROPE = rope(var, ROPE_bounds)$rope_probability + ) + + contrasts <- rbind(contrasts, var) + } + output <- list(means = means, contrasts = contrasts) + return(output) + } else { + warning("you need to specify ROPE_bounds (e.g. 'c(-0.1, 0.1)'). ROPE is not computed.") + } + } + for (name in names(contrasts_posterior)) { var <- contrasts_posterior[[name]] @@ -92,8 +119,6 @@ get_contrasts.stanreg <- function(fit, formula, prob=0.9, ...) { contrasts <- rbind(contrasts, var) } - - output <- list(means = means, contrasts = contrasts) return(output) } From bb055d3adea2c153354f849587fa5a970e830326 Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Wed, 17 Oct 2018 18:57:26 +0200 Subject: [PATCH 07/17] Last update before breaking changes in get_contrasts --- DESCRIPTION | 2 +- NAMESPACE | 2 + R/find_season.R | 32 ++++-- R/get_contrasts.R | 3 +- R/get_contrasts.glmerMod.R | 2 +- R/get_contrasts.lm.R | 62 +++++++++++ R/get_contrasts.lmerModLmerTest.R | 4 +- R/golden.R | 19 ++++ R/interpret_odds.R | 4 +- docs/_posts/preparation/polynomial.Rmd | 144 +++++++++++++++++++++++++ man/find_season.Rd | 20 +++- man/get_contrasts.Rd | 3 +- man/get_contrasts.glmerMod.Rd | 2 +- man/get_contrasts.lm.Rd | 39 +++++++ man/get_contrasts.lmerModLmerTest.Rd | 4 +- man/golden.Rd | 24 +++++ man/interpret_odds.Rd | 4 +- 17 files changed, 344 insertions(+), 26 deletions(-) create mode 100644 R/get_contrasts.lm.R create mode 100644 R/golden.R create mode 100644 docs/_posts/preparation/polynomial.Rmd create mode 100644 man/get_contrasts.lm.Rd create mode 100644 man/golden.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 4485cea..ab0c9f4 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: psycho Type: Package Title: Efficient and Publishing-Oriented Workflow for Psychological Science -Version: 0.3.8 +Version: 0.3.9 Authors@R: c( person("Dominique", "Makowski", diff --git a/NAMESPACE b/NAMESPACE index a18c8b7..053c2c6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,6 +20,7 @@ S3method(get_R2,lm) S3method(get_R2,merMod) S3method(get_R2,stanreg) S3method(get_contrasts,glmerMod) +S3method(get_contrasts,lm) S3method(get_contrasts,lmerModLmerTest) S3method(get_contrasts,stanreg) S3method(get_data,lm) @@ -88,6 +89,7 @@ export(get_formula) export(get_info) export(get_loadings_max) export(get_predicted) +export(golden) export(interpret_R2) export(interpret_R2_posterior) export(interpret_RMSEA) diff --git a/R/find_season.R b/R/find_season.R index 429e879..2120631 100644 --- a/R/find_season.R +++ b/R/find_season.R @@ -2,24 +2,38 @@ #' #' Returns the season of an array of dates. #' -#' @param date Array of dates. Must cover the 4 seasons. +#' @param dates Array of dates. +#' @param winter month-day of winter solstice. +#' @param spring month-day of spring equinox. +#' @param summer month-day of summer solstice. +#' @param fall month-day of fall equinox. #' #' @return season #' #' @examples #' library(psycho) #' -#' dates <- c("2017-02-15", "2017-05-15", "2017-08-15", "2017-11-15") +#' dates <- c("2012-02-15", "2017-05-15", "2009-08-15", "1912-11-15") #' find_season(dates) #' -#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' @author Josh O'Brien +#' +#' @seealso +#' https://stackoverflow.com/questions/9500114/find-which-season-a-particular-date-belongs-to #' #' @export -find_season <- function(date) { - d <- as.Date(cut(as.Date(date), "month")) + 32 - season <- factor( - quarters(d), - labels = c("Winter", "Spring", "Summer", "Fall") - ) +find_season <- function(dates, winter="12-21", spring="3-20", summer="6-21", fall="9-22") { + + WS <- as.Date(paste0("2012-", winter), format = "%Y-%m-%d") # Winter Solstice + SE <- as.Date(paste0("2012-", spring), format = "%Y-%m-%d") # Spring Equinox + SS <- as.Date(paste0("2012-", summer), format = "%Y-%m-%d") # Summer Solstice + FE <- as.Date(paste0("2012-", fall), format = "%Y-%m-%d") # Fall Equinox + + # Convert dates from any year to 2012 dates + d <- as.Date(strftime(as.character(dates), format="2012-%m-%d")) + + season <- ifelse (d >= WS | d < SE, "Winter", + ifelse (d >= SE & d < SS, "Spring", + ifelse (d >= SS & d < FE, "Summer", "Fall"))) return(season) } diff --git a/R/get_contrasts.R b/R/get_contrasts.R index d3b5fe1..9e21967 100644 --- a/R/get_contrasts.R +++ b/R/get_contrasts.R @@ -4,8 +4,9 @@ #' documentation for your model's class: #' \itemize{ #' \item{\link[=get_contrasts.stanreg]{get_contrasts.stanreg}} -#' \item{\link[=get_contrasts.lmerModLmerTest]{get_contrasts.merModLmerTest}} +#' \item{\link[=get_contrasts.lmerModLmerTest]{get_contrasts.lmerModLmerTest}} #' \item{\link[=get_contrasts.glmerMod]{get_contrasts.glmerMod}} +#' \item{\link[=get_contrasts.lm]{get_contrasts.lm}} #' } #' #' diff --git a/R/get_contrasts.glmerMod.R b/R/get_contrasts.glmerMod.R index b141a94..d89fcc8 100644 --- a/R/get_contrasts.glmerMod.R +++ b/R/get_contrasts.glmerMod.R @@ -1,6 +1,6 @@ #' Compute estimated marginal means and contrasts from glmerMod models. #' -#' Compute estimated marginal means and contrasts from a glmerMod models. +#' Compute estimated marginal means and contrasts from a glmerMod model. #' #' @param fit A glmerMod model. #' @param formula A character vector (formula like format, i.e., including diff --git a/R/get_contrasts.lm.R b/R/get_contrasts.lm.R new file mode 100644 index 0000000..7ebdd90 --- /dev/null +++ b/R/get_contrasts.lm.R @@ -0,0 +1,62 @@ +#' Compute estimated marginal means and contrasts from lm models. +#' +#' Compute estimated marginal means and contrasts from an lm model. +#' +#' @param fit An lm model. +#' @param formula A character vector (formula like format, i.e., including +#' interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. +#' @param adjust P value adjustment method. Default is "tukey". Can be "holm", +#' "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr" or "none". +#' @param ... Arguments passed to or from other methods. +#' +#' +#' @return list with estimated marginal means (95% CI) and contrasts. +#' +#' +#' @examples +#' \dontrun{ +#' library(psycho) +#' require(lmerTest) +#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season + (1|Salary), data=affective) +#' +#' contrasts <- get_contrasts(fit, formula="Birth_Season", adjust="tukey") +#' contrasts$means +#' contrasts$contrasts +#' } +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @method get_contrasts lm +#' @import dplyr +#' @importFrom emmeans emmeans +#' @importFrom graphics pairs +#' @importFrom stats confint mad +#' +#' @export +get_contrasts.lm <- function(fit, formula, adjust="tukey", ...) { + formula <- as.formula(paste0("~", formula)) + + + # emmeans --------------------------------------------------------------- + means <- fit %>% + emmeans::emmeans(formula) %>% + as.data.frame() %>% + dplyr::rename_( + "Mean" = "emmean", + "CI_lower" = "lower.CL", + "CI_higher" = "upper.CL" + ) + + + # Contrasts --------------------------------------------------------------- + contrasts <- fit %>% + emmeans::emmeans(formula) %>% + graphics::pairs(adjust = adjust) %>% + as.data.frame() %>% + dplyr::rename_( + "Contrast" = "contrast", + "Difference" = "estimate" + ) + + output <- list(means = means, contrasts = contrasts) + return(output) +} diff --git a/R/get_contrasts.lmerModLmerTest.R b/R/get_contrasts.lmerModLmerTest.R index e43a8df..af585d4 100644 --- a/R/get_contrasts.lmerModLmerTest.R +++ b/R/get_contrasts.lmerModLmerTest.R @@ -1,8 +1,8 @@ #' Compute estimated marginal means and contrasts from lmerModLmerTest models. #' -#' Compute estimated marginal means and contrasts from a lmerModLmerTest models. +#' Compute estimated marginal means and contrasts from an lmerModLmerTest model. #' -#' @param fit A merModLmerTest model. +#' @param fit An merModLmerTest model. #' @param formula A character vector (formula like format, i.e., including #' interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. #' @param adjust P value adjustment method. Default is "tukey". Can be "holm", diff --git a/R/golden.R b/R/golden.R new file mode 100644 index 0000000..05d67e2 --- /dev/null +++ b/R/golden.R @@ -0,0 +1,19 @@ +#' Golden Ratio. +#' +#' Returns the golden ratio (1.618034...). +#' +#' @param x A number to be multiplied by the golden ratio. The default (x=1) returns the value of the golden ratio. +#' +#' @examples +#' library(psycho) +#' +#' golden() +#' golden(8) +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @export +golden <- function(x=1) { + return(x*(1+sqrt(5))/2) +} + diff --git a/R/interpret_odds.R b/R/interpret_odds.R index 8722bb9..fc2d0c9 100644 --- a/R/interpret_odds.R +++ b/R/interpret_odds.R @@ -1,6 +1,6 @@ -#' Omega Squared Interpretation +#' Odds ratio interpreation for a posterior distribution. #' -#' Return the interpretation of Omegas Squared. +#' Interpret odds with a set of rules. #' #' @param x Odds ratio. #' @param log Are these log odds ratio? diff --git a/docs/_posts/preparation/polynomial.Rmd b/docs/_posts/preparation/polynomial.Rmd new file mode 100644 index 0000000..d9d9db2 --- /dev/null +++ b/docs/_posts/preparation/polynomial.Rmd @@ -0,0 +1,144 @@ +--- +title: "Modelling Curves: Fitting Polynomials Models" +layout: post +output: + md_document: + toc: yes + variant: markdown_github + html_document: + df_print: paged + toc: yes +author: "Dominique Makowski" +date: "`r Sys.Date()`" +editor_options: + chunk_output_type: console +--- + + +```{r message=FALSE, warning=FALSE, include=FALSE} +library(knitr) +``` + + +# Observed Data + +```{r, fig.width=7, fig.height=4.5, eval = TRUE, results='markup', fig.align='center', comment=NA, message=FALSE, warning=FALSE} +library(tidyverse) +library(psycho) + + +df <- psycho::affective +``` + + +```{r, fig.width=7, fig.height=4.5, eval = TRUE, results='markup', fig.align='center', comment=NA, message=FALSE, warning=FALSE} +plot <- df %>% + ggplot(aes(x=Adjusting, y=Life_Satisfaction)) + + geom_count() + + geom_smooth(method="loess", color="black", fill="black", alpha=0.1) + + theme_classic() +plot +``` + + + +# Linear Fit + +## Model + +```{r, fig.width=7, fig.height=4.5, eval = TRUE, results='hide', fig.align='center', comment=NA, message=FALSE, warning=FALSE} +fit <- lm(Life_Satisfaction ~ Adjusting, data=df) + +analyze(fit) +``` + +## Visualize + +```{r, fig.width=7, fig.height=4.5, eval = TRUE, results='markup', fig.align='center', comment=NA, message=FALSE, warning=FALSE} +data_linear <- df %>% + select(Adjusting) %>% + refdata(length.out=100) %>% + get_predicted(fit, .) + +plot <- plot + + geom_ribbon(data=data_linear, + aes(y=Life_Satisfaction_Predicted, ymin=Life_Satisfaction_CI_2.5, ymax=Life_Satisfaction_CI_97.5), + fill="red", + alpha=0.1) + + geom_line(data=data_linear, + aes(y=Life_Satisfaction_Predicted), + color="red") +plot +``` + +# Polynomial fit + +```{r, fig.width=7, fig.height=4.5, eval = TRUE, results='hide', fig.align='center', comment=NA, message=FALSE, warning=FALSE} +fit <- lm(Life_Satisfaction ~ poly(Adjusting, 2), data=df) + +analyze(fit) +``` + +## Visualize + +To add the predictions of this model, we use the exact same code as for the linear model. + +```{r, fig.width=7, fig.height=4.5, eval = TRUE, results='markup', fig.align='center', comment=NA, message=FALSE, warning=FALSE} +data_poly <- df %>% + select(Adjusting) %>% + refdata(length.out=100) %>% + get_predicted(fit, .) + +plot <- plot + + geom_ribbon(data=data_poly, + aes(y=Life_Satisfaction_Predicted, ymin=Life_Satisfaction_CI_2.5, ymax=Life_Satisfaction_CI_97.5), + fill="blue", + alpha=0.1) + + geom_line(data=data_poly, + aes(y=Life_Satisfaction_Predicted), + color="blue") +plot +``` + + +# Raw and Orthogonal Polynomials: Interpretation + + +```{r, fig.width=7, fig.height=4.5, eval = TRUE, results='hide', fig.align='center', comment=NA, message=FALSE, warning=FALSE} +data <- data.frame(x=seq(from=1, to=5, length.out=100), + y=4 - 0.6*x + 0.1*x^2 + 0.25*rnorm(100)) + +ggplot(data, aes(x, y)) + geom_point() + + geom_smooth(method = "lm", formula = y ~ poly(x, 2)) + +summary(lm(y ~ poly(x, 2, raw=TRUE))) +summary(lm(y ~ poly(x, 2))) +``` + +- Use raw polynomials if you're interested in the coefficient and/or the regression equation. +- Use orthogonal if you're interested in the general shape of the relationship. + +# Contribute + +**psycho is a young package in need of affection**. Therefore, if you have any advices, opinions or such, we encourage you to either let us know by opening an [issue](https://github.com/neuropsychology/psycho.R/issues), or by [contributing](https://github.com/neuropsychology/psycho.R/blob/master/.github/CONTRIBUTING.md) to the code. + + +# Credits + +This package helped you? Don't forget to cite the various packages you used :) + +You can cite `psycho` as follows: + +- Makowski, (2018). *The psycho Package: An Efficient and Publishing-Oriented Workflow for Psychological Science*. Journal of Open Source Software, 3(22), 470. https://doi.org/10.21105/joss.00470 + + +# Previous blogposts + +- [APA Formatted Bayesian Correlation](https://neuropsychology.github.io/psycho.R/2018/06/11/bayesian_correlation.html) +- [Fancy Plot (with Posterior Samples) for Bayesian Regressions](https://neuropsychology.github.io/psycho.R/2018/06/03/plot_bayesian_model.html) +- [How Many Factors to Retain in Factor Analysis](https://neuropsychology.github.io/psycho.R/2018/05/24/n_factors.html) +- [Beautiful and Powerful Correlation Tables](https://neuropsychology.github.io/psycho.R/2018/05/20/correlation.html) +- [Format and Interpret Linear Mixed Models](https://neuropsychology.github.io/psycho.R/2018/05/10/interpret_mixed_models.html) +- [How to do Repeated Measures ANOVAs](https://neuropsychology.github.io/psycho.R/2018/05/01/repeated_measure_anovas.html) +- [Standardize (Z-score) a dataframe](https://neuropsychology.github.io/psycho.R/2018/03/29/standardize.html) +- [Compute Signal Detection Theory Indices](https://neuropsychology.github.io/psycho.R/2018/03/29/SDT.html) diff --git a/man/find_season.Rd b/man/find_season.Rd index fb44373..eeb2af6 100644 --- a/man/find_season.Rd +++ b/man/find_season.Rd @@ -4,10 +4,19 @@ \alias{find_season} \title{Find season of dates.} \usage{ -find_season(date) +find_season(dates, winter = "12-21", spring = "3-20", + summer = "6-21", fall = "9-22") } \arguments{ -\item{date}{Array of dates. Must cover the 4 seasons.} +\item{dates}{Array of dates.} + +\item{winter}{month-day of winter solstice.} + +\item{spring}{month-day of spring equinox.} + +\item{summer}{month-day of summer solstice.} + +\item{fall}{month-day of fall equinox.} } \value{ season @@ -18,10 +27,13 @@ Returns the season of an array of dates. \examples{ library(psycho) -dates <- c("2017-02-15", "2017-05-15", "2017-08-15", "2017-11-15") +dates <- c("2012-02-15", "2017-05-15", "2009-08-15", "1912-11-15") find_season(dates) +} +\seealso{ +https://stackoverflow.com/questions/9500114/find-which-season-a-particular-date-belongs-to } \author{ -\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +Josh O'Brien } diff --git a/man/get_contrasts.Rd b/man/get_contrasts.Rd index 5cbb3eb..9f39fe7 100644 --- a/man/get_contrasts.Rd +++ b/man/get_contrasts.Rd @@ -16,8 +16,9 @@ Compute estimated marginal means and contrasts from models. See the documentation for your model's class: \itemize{ \item{\link[=get_contrasts.stanreg]{get_contrasts.stanreg}} - \item{\link[=get_contrasts.lmerModLmerTest]{get_contrasts.merModLmerTest}} + \item{\link[=get_contrasts.lmerModLmerTest]{get_contrasts.lmerModLmerTest}} \item{\link[=get_contrasts.glmerMod]{get_contrasts.glmerMod}} + \item{\link[=get_contrasts.lm]{get_contrasts.lm}} } } \author{ diff --git a/man/get_contrasts.glmerMod.Rd b/man/get_contrasts.glmerMod.Rd index 136f672..3ae636c 100644 --- a/man/get_contrasts.glmerMod.Rd +++ b/man/get_contrasts.glmerMod.Rd @@ -21,7 +21,7 @@ interactions or nesting terms) specifying the names of the predictors over which list with estimated marginal means (95% CI) and contrasts. } \description{ -Compute estimated marginal means and contrasts from a glmerMod models. +Compute estimated marginal means and contrasts from a glmerMod model. } \examples{ \dontrun{ diff --git a/man/get_contrasts.lm.Rd b/man/get_contrasts.lm.Rd new file mode 100644 index 0000000..e5b00b8 --- /dev/null +++ b/man/get_contrasts.lm.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_contrasts.lm.R +\name{get_contrasts.lm} +\alias{get_contrasts.lm} +\title{Compute estimated marginal means and contrasts from lm models.} +\usage{ +\method{get_contrasts}{lm}(fit, formula, adjust = "tukey", ...) +} +\arguments{ +\item{fit}{An lm model.} + +\item{formula}{A character vector (formula like format, i.e., including +interactions or nesting terms) specifying the names of the predictors over which EMMs are desired.} + +\item{adjust}{P value adjustment method. Default is "tukey". Can be "holm", +"hochberg", "hommel", "bonferroni", "BH", "BY", "fdr" or "none".} + +\item{...}{Arguments passed to or from other methods.} +} +\value{ +list with estimated marginal means (95% CI) and contrasts. +} +\description{ +Compute estimated marginal means and contrasts from an lm model. +} +\examples{ +\dontrun{ +library(psycho) +require(lmerTest) +fit <- lmerTest::lmer(Adjusting ~ Birth_Season + (1|Salary), data=affective) + +contrasts <- get_contrasts(fit, formula="Birth_Season", adjust="tukey") +contrasts$means +contrasts$contrasts +} +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/get_contrasts.lmerModLmerTest.Rd b/man/get_contrasts.lmerModLmerTest.Rd index 87da4d2..1c9c24c 100644 --- a/man/get_contrasts.lmerModLmerTest.Rd +++ b/man/get_contrasts.lmerModLmerTest.Rd @@ -8,7 +8,7 @@ ...) } \arguments{ -\item{fit}{A merModLmerTest model.} +\item{fit}{An merModLmerTest model.} \item{formula}{A character vector (formula like format, i.e., including interactions or nesting terms) specifying the names of the predictors over which EMMs are desired.} @@ -22,7 +22,7 @@ interactions or nesting terms) specifying the names of the predictors over which list with estimated marginal means (95% CI) and contrasts. } \description{ -Compute estimated marginal means and contrasts from a lmerModLmerTest models. +Compute estimated marginal means and contrasts from an lmerModLmerTest model. } \examples{ \dontrun{ diff --git a/man/golden.Rd b/man/golden.Rd new file mode 100644 index 0000000..0f8b000 --- /dev/null +++ b/man/golden.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/golden.R +\name{golden} +\alias{golden} +\title{Golden Ratio.} +\usage{ +golden(x = 1) +} +\arguments{ +\item{x}{A number to be multiplied by the golden ratio. The default (x=1) returns the value of the golden ratio.} +} +\description{ +Returns the golden ratio (1.618034...). +} +\examples{ +library(psycho) + +golden() +golden(8) + +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/interpret_odds.Rd b/man/interpret_odds.Rd index 529f8bd..24fe6bd 100644 --- a/man/interpret_odds.Rd +++ b/man/interpret_odds.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/interpret_odds.R \name{interpret_odds} \alias{interpret_odds} -\title{Omega Squared Interpretation} +\title{Odds ratio interpreation for a posterior distribution.} \usage{ interpret_odds(x, log = FALSE, direction = FALSE, rules = "chen2010") } @@ -16,7 +16,7 @@ interpret_odds(x, log = FALSE, direction = FALSE, rules = "chen2010") \item{rules}{Can be "chen2010" (default), "cohen1988" (through \link[=odds_to_d]{log odds to Cohen's d transformation}) or a custom list.} } \description{ -Return the interpretation of Omegas Squared. +Interpret odds with a set of rules. } \examples{ library(psycho) From 02c627bfa0dd94353021ca4a9e1a7eb3f3ba8c6c Mon Sep 17 00:00:00 2001 From: Dominique Makowski Date: Thu, 18 Oct 2018 17:05:23 +0200 Subject: [PATCH 08/17] breaking change: separate get_constrasts and get_means separated get_constrasts and get_means --- DESCRIPTION | 3 +- NAMESPACE | 10 +- R/analyze.stanreg.R | 2 +- R/get_contrasts.R | 229 ++++- R/get_contrasts.glmerMod.R | 63 -- R/get_contrasts.lm.R | 62 -- R/get_contrasts.lmerModLmerTest.R | 62 -- R/get_contrasts.stanreg.R | 124 --- R/get_means.R | 152 ++++ docs/~$index.html | Bin 0 -> 162 bytes man/analyze.stanreg.Rd | 2 +- man/get_contrasts.Rd | 37 +- man/get_contrasts.glm.Rd | 25 + man/get_contrasts.glmerMod.Rd | 34 +- man/get_contrasts.lm.Rd | 32 +- man/get_contrasts.lmerMod.Rd | 25 + man/get_contrasts.lmerModLmerTest.Rd | 33 +- man/get_contrasts.stanreg.Rd | 39 +- man/get_means.Rd | 45 + tests/testthat/test-get_contrasts.R | 34 + tests/testthat/test-get_contrasts.glmerMod.R | 15 - .../test-get_contrasts.lmerModLmerTest.R | 17 - tests/testthat/test-get_contrasts.stanreg.R | 16 - tests/testthat/test-get_means.R | 37 + vignettes/bayesian.R | 14 +- vignettes/bayesian.Rmd | 16 +- vignettes/bayesian.html | 318 +++---- vignettes/bayesian.knit.md | 812 ------------------ 28 files changed, 794 insertions(+), 1464 deletions(-) delete mode 100644 R/get_contrasts.glmerMod.R delete mode 100644 R/get_contrasts.lm.R delete mode 100644 R/get_contrasts.lmerModLmerTest.R delete mode 100644 R/get_contrasts.stanreg.R create mode 100644 R/get_means.R create mode 100644 docs/~$index.html create mode 100644 man/get_contrasts.glm.Rd create mode 100644 man/get_contrasts.lmerMod.Rd create mode 100644 man/get_means.Rd create mode 100644 tests/testthat/test-get_contrasts.R delete mode 100644 tests/testthat/test-get_contrasts.glmerMod.R delete mode 100644 tests/testthat/test-get_contrasts.lmerModLmerTest.R delete mode 100644 tests/testthat/test-get_contrasts.stanreg.R create mode 100644 tests/testthat/test-get_means.R delete mode 100644 vignettes/bayesian.knit.md diff --git a/DESCRIPTION b/DESCRIPTION index ab0c9f4..bce5228 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: psycho Type: Package Title: Efficient and Publishing-Oriented Workflow for Psychological Science -Version: 0.3.9 +Version: 0.4.0 Authors@R: c( person("Dominique", "Makowski", @@ -49,7 +49,6 @@ Imports: MuMIn, lme4, lmerTest, - coda, emmeans (>= 1.2.2), broom, tibble, diff --git a/NAMESPACE b/NAMESPACE index 053c2c6..64c70ed 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -19,8 +19,10 @@ S3method(get_R2,glm) S3method(get_R2,lm) S3method(get_R2,merMod) S3method(get_R2,stanreg) +S3method(get_contrasts,glm) S3method(get_contrasts,glmerMod) S3method(get_contrasts,lm) +S3method(get_contrasts,lmerMod) S3method(get_contrasts,lmerModLmerTest) S3method(get_contrasts,stanreg) S3method(get_data,lm) @@ -38,6 +40,12 @@ S3method(get_info,lm) S3method(get_info,lmerMod) S3method(get_info,lmerModLmerTest) S3method(get_info,stanreg) +S3method(get_means,glm) +S3method(get_means,glmerMod) +S3method(get_means,lm) +S3method(get_means,lmerMod) +S3method(get_means,lmerModLmerTest) +S3method(get_means,stanreg) S3method(get_predicted,glm) S3method(get_predicted,lm) S3method(get_predicted,merMod) @@ -88,6 +96,7 @@ export(get_data) export(get_formula) export(get_info) export(get_loadings_max) +export(get_means) export(get_predicted) export(golden) export(interpret_R2) @@ -126,7 +135,6 @@ export(simulate_data_regression) export(standardize) export(values) import(broom) -import(coda) import(dplyr) import(ggcorrplot) import(ggplot2) diff --git a/R/analyze.stanreg.R b/R/analyze.stanreg.R index c189d2c..b76978c 100644 --- a/R/analyze.stanreg.R +++ b/R/analyze.stanreg.R @@ -5,7 +5,7 @@ #' @param x A stanreg model. #' @param CI Credible interval bounds. #' @param index Index of effect existence to report. Can be 'overlap' or 'ROPE'. -#' @param ROPE_bounds Bounds ot the ROPE. If NULL and effsize is TRUE, than the ROPE. +#' @param ROPE_bounds Bounds of the ROPE. If NULL and effsize is TRUE, than the ROPE. #' will have default values c(-0.1, 0.1) and computed on the standardized posteriors. #' @param effsize Compute Effect Sizes according to Cohen (1988). For linear models only. #' @param effsize_rules Grid for effect size interpretation. See \link[=interpret_d]{interpret_d}. diff --git a/R/get_contrasts.R b/R/get_contrasts.R index 9e21967..d074de5 100644 --- a/R/get_contrasts.R +++ b/R/get_contrasts.R @@ -1,24 +1,237 @@ -#' Get Marginal Means and Contrasts. +#' Compute estimated contrasts from models. #' -#' Compute estimated marginal means and contrasts from models. See the -#' documentation for your model's class: +#' Compute estimated contrasts between factor levels based on a fitted model. +#' See the documentation for your model's class: #' \itemize{ -#' \item{\link[=get_contrasts.stanreg]{get_contrasts.stanreg}} -#' \item{\link[=get_contrasts.lmerModLmerTest]{get_contrasts.lmerModLmerTest}} +#' \item{\link[=get_contrasts.glm]{get_contrasts.glm}} +#' \item{\link[=get_contrasts.lmerModLmerTest]{get_contrasts.merModLmerTest}} #' \item{\link[=get_contrasts.glmerMod]{get_contrasts.glmerMod}} -#' \item{\link[=get_contrasts.lm]{get_contrasts.lm}} +#' \item{\link[=get_contrasts.stanreg]{get_contrasts.stanreg}} #' } #' #' -#' -#' @param fit Model. +#' @param fit A model. #' @param ... Arguments passed to or from other methods. #' +#' @return Estimated contrasts. +#' +#' +#' @examples +#' \dontrun{ +#' library(psycho) +#' require(lmerTest) +#' require(rstanarm) #' +#' fit <- lm(Adjusting ~ Birth_Season * Salary, data=affective) +#' get_contrasts(fit) #' +#' fit <- lm(Adjusting ~ Birth_Season * Salary, data=affective) +#' get_contrasts(fit, adjust="bonf") +#' +#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1|Salary), data=affective) +#' get_contrasts(fit, formula="Birth_Season") +#' +#' fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data=affective) +#' get_contrasts(fit, formula="Birth_Season", ROPE_bounds=c(-0.1, 0.1)) +#' +#' } #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' +#' #' @export get_contrasts <- function(fit, ...) { UseMethod("get_contrasts") } + + +#' Compute estimated contrasts from models. +#' +#' Compute estimated contrasts from models. +#' +#' @param fit A Bayesian model. +#' @param formula A character vector (formula like format, i.e., including +#' interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. +#' @param CI Determine the confidence or credible interval bounds. +#' @param ROPE_bounds Optional bounds of the ROPE for Bayesian models. +#' @param overlap Set to TRUE to add Overlap index (for Bayesian models). +#' @param ... Arguments passed to or from other methods. +#' @method get_contrasts stanreg +#' @export +get_contrasts.stanreg <- function(fit, formula=NULL, CI=90, ROPE_bounds=NULL, overlap=FALSE, ...){ + .get_contrasts_bayes(fit, formula, CI, ROPE_bounds, overlap, ...) +} + + +#' Compute estimated contrasts from models. +#' +#' Compute estimated contrasts from models. +#' +#' @param fit A frequentist model. +#' @param formula A character vector (formula like format, i.e., including +#' interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. +#' @param CI Determine the confidence or credible interval bounds. +#' @param adjust P value adjustment method for frequentist models. Default is "tukey". Can be "holm", +#' "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr" or "none". +#' @param ... Arguments passed to or from other methods. +#' @method get_contrasts lm +#' @export +get_contrasts.lm <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ + .get_contrasts_freq(fit, formula, CI, adjust, ...) +} + +#' Compute estimated contrasts from models. +#' +#' Compute estimated contrasts from models. +#' +#' @inheritParams get_contrasts.lm +#' @method get_contrasts glm +#' @export +get_contrasts.glm <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ + .get_contrasts_freq(fit, formula, CI, adjust, ...) +} + +#' Compute estimated contrasts from models. +#' +#' Compute estimated contrasts from models. +#' +#' @inheritParams get_contrasts.lm +#' @method get_contrasts lmerModLmerTest +#' @export +get_contrasts.lmerModLmerTest <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ + .get_contrasts_freq(fit, formula, CI, adjust, ...) +} + +#' Compute estimated contrasts from models. +#' +#' Compute estimated contrasts from models. +#' +#' @inheritParams get_contrasts.lm +#' @method get_contrasts glmerMod +#' @export +get_contrasts.glmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ + .get_contrasts_freq(fit, formula, CI, adjust, ...) +} + +#' Compute estimated contrasts from models. +#' +#' Compute estimated contrasts from models. +#' +#' @inheritParams get_contrasts.lm +#' @method get_contrasts lmerMod +#' @export +get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ + .get_contrasts_freq(fit, formula, CI, adjust, ...) +} + + + + +#' @import dplyr +#' @importFrom emmeans emmeans +#' @importFrom graphics pairs +#' @importFrom stats confint mad +#' @keywords internal +.get_contrasts_bayes <- function(fit, formula=NULL, CI=90, ROPE_bounds=NULL, overlap=FALSE, ...) { + + if(is.null(formula)){ + formula <- paste(get_info(fit)$predictors, collapse=" * ") + } + + if(is.character(formula)){ + formula <- as.formula(paste0("~ ", formula)) + } + + # Contrasts --------------------------------------------------------------- + contrasts_posterior <- fit %>% + emmeans::emmeans(formula) %>% + graphics::pairs() %>% + emmeans::as.mcmc.emmGrid() %>% + as.matrix() %>% + as.data.frame() + + contrasts <- data.frame() + + + for (name in names(contrasts_posterior)) { + posterior <- contrasts_posterior[[name]] + + CI_values <- HDI(posterior, prob = CI/100) + CI_values <- c(CI_values$values$HDImin, CI_values$values$HDImax) + + var <- data.frame( + Contrast = stringr::str_remove(name, "contrast "), + Median = median(posterior), + MAD = mad(posterior), + CI_lower = CI_values[seq(1, length(CI_values), 2)], + CI_higher = CI_values[seq(2, length(CI_values), 2)], + MPE = mpe(posterior)$MPE + ) + + if(overlap == TRUE){ + var$Overlap <- 100 * overlap( + posterior, + rnorm_perfect( + length(posterior), + 0, + sd(posterior) + ) + ) + } + + if(!is.null(ROPE_bounds)){ + var$ROPE <- rope(posterior, ROPE_bounds, CI = 95)$rope_probability + } + + contrasts <- rbind(contrasts, var) + } + + + return(contrasts) +} + + + + +#' @import dplyr +#' @importFrom emmeans emmeans +#' @importFrom graphics pairs +#' @importFrom stats confint +#' @keywords internal +.get_contrasts_freq <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) { + + if(is.null(formula)){ + formula <- paste(get_info(fit)$predictors, collapse=" * ") + } + + if(is.character(formula)){ + formula <- as.formula(paste0("~ ", formula)) + } + + # Contrasts --------------------------------------------------------------- + contrasts <- fit %>% + emmeans::emmeans(formula) %>% + graphics::pairs(adjust = adjust) + + # Confint + CI <- contrasts %>% + confint(CI/100) %>% + select(contains("CL")) + + + contrasts <- contrasts %>% + as.data.frame() %>% + cbind(CI) %>% + dplyr::rename_( + "Contrast" = "contrast", + "Difference" = "estimate", + "p" = "p.value" + ) + names(contrasts) <- stringr::str_replace(names(contrasts), "lower.CL", "CI_lower") + names(contrasts) <- stringr::str_replace(names(contrasts), "upper.CL", "CI_upper") + names(contrasts) <- stringr::str_replace(names(contrasts), "asymp.LCL", "CI_lower") + names(contrasts) <- stringr::str_replace(names(contrasts), "asymp.UCL", "CI_upper") + names(contrasts) <- stringr::str_replace(names(contrasts), "t.ratio", "t") + names(contrasts) <- stringr::str_replace(names(contrasts), "z.ratio", "z") + + return(contrasts) +} diff --git a/R/get_contrasts.glmerMod.R b/R/get_contrasts.glmerMod.R deleted file mode 100644 index d89fcc8..0000000 --- a/R/get_contrasts.glmerMod.R +++ /dev/null @@ -1,63 +0,0 @@ -#' Compute estimated marginal means and contrasts from glmerMod models. -#' -#' Compute estimated marginal means and contrasts from a glmerMod model. -#' -#' @param fit A glmerMod model. -#' @param formula A character vector (formula like format, i.e., including -#' interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. -#' @param adjust P value adjustment method. Default is "tukey". Can be "holm", -#' "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr", "none". -#' @param ... Arguments passed to or from other methods. -#' -#' -#' @return list with estimated marginal means (95% CI) and contrasts. -#' -#' -#' @examples -#' \dontrun{ -#' library(psycho) -#' require(lme4) -#' fit <- lme4::glmer(Sex ~ Birth_Season + (1|Salary), data=affective, family="binomial") -#' -#' contrasts <- get_contrasts(fit, formula="Birth_Season", adjust="tukey") -#' contrasts$means -#' contrasts$contrasts -#' } -#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} -#' -#' @method get_contrasts glmerMod -#' @import coda -#' @importFrom emmeans emmeans -#' @importFrom graphics pairs -#' @importFrom stats confint mad -#' -#' @export -get_contrasts.glmerMod <- function(fit, formula, adjust="tukey", ...) { - formula <- as.formula(paste0("~", formula)) - - - # emmeans --------------------------------------------------------------- - means <- fit %>% - emmeans::emmeans(formula) %>% - as.data.frame() %>% - rename_( - "Mean" = "emmean", - "CI_lower" = "asymp.LCL", - "CI_higher" = "asymp.UCL" - ) - means$Probability <- odds_to_probs(means$Mean) - - - # Contrasts --------------------------------------------------------------- - contrasts <- fit %>% - emmeans::emmeans(formula) %>% - graphics::pairs(adjust = adjust) %>% - as.data.frame() %>% - rename_( - "Contrast" = "contrast", - "Difference" = "estimate" - ) - - output <- list(means = means, contrasts = contrasts) - return(output) -} diff --git a/R/get_contrasts.lm.R b/R/get_contrasts.lm.R deleted file mode 100644 index 7ebdd90..0000000 --- a/R/get_contrasts.lm.R +++ /dev/null @@ -1,62 +0,0 @@ -#' Compute estimated marginal means and contrasts from lm models. -#' -#' Compute estimated marginal means and contrasts from an lm model. -#' -#' @param fit An lm model. -#' @param formula A character vector (formula like format, i.e., including -#' interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. -#' @param adjust P value adjustment method. Default is "tukey". Can be "holm", -#' "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr" or "none". -#' @param ... Arguments passed to or from other methods. -#' -#' -#' @return list with estimated marginal means (95% CI) and contrasts. -#' -#' -#' @examples -#' \dontrun{ -#' library(psycho) -#' require(lmerTest) -#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season + (1|Salary), data=affective) -#' -#' contrasts <- get_contrasts(fit, formula="Birth_Season", adjust="tukey") -#' contrasts$means -#' contrasts$contrasts -#' } -#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} -#' -#' @method get_contrasts lm -#' @import dplyr -#' @importFrom emmeans emmeans -#' @importFrom graphics pairs -#' @importFrom stats confint mad -#' -#' @export -get_contrasts.lm <- function(fit, formula, adjust="tukey", ...) { - formula <- as.formula(paste0("~", formula)) - - - # emmeans --------------------------------------------------------------- - means <- fit %>% - emmeans::emmeans(formula) %>% - as.data.frame() %>% - dplyr::rename_( - "Mean" = "emmean", - "CI_lower" = "lower.CL", - "CI_higher" = "upper.CL" - ) - - - # Contrasts --------------------------------------------------------------- - contrasts <- fit %>% - emmeans::emmeans(formula) %>% - graphics::pairs(adjust = adjust) %>% - as.data.frame() %>% - dplyr::rename_( - "Contrast" = "contrast", - "Difference" = "estimate" - ) - - output <- list(means = means, contrasts = contrasts) - return(output) -} diff --git a/R/get_contrasts.lmerModLmerTest.R b/R/get_contrasts.lmerModLmerTest.R deleted file mode 100644 index af585d4..0000000 --- a/R/get_contrasts.lmerModLmerTest.R +++ /dev/null @@ -1,62 +0,0 @@ -#' Compute estimated marginal means and contrasts from lmerModLmerTest models. -#' -#' Compute estimated marginal means and contrasts from an lmerModLmerTest model. -#' -#' @param fit An merModLmerTest model. -#' @param formula A character vector (formula like format, i.e., including -#' interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. -#' @param adjust P value adjustment method. Default is "tukey". Can be "holm", -#' "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr" or "none". -#' @param ... Arguments passed to or from other methods. -#' -#' -#' @return list with estimated marginal means (95% CI) and contrasts. -#' -#' -#' @examples -#' \dontrun{ -#' library(psycho) -#' require(lmerTest) -#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season + (1|Salary), data=affective) -#' -#' contrasts <- get_contrasts(fit, formula="Birth_Season", adjust="tukey") -#' contrasts$means -#' contrasts$contrasts -#' } -#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} -#' -#' @method get_contrasts lmerModLmerTest -#' @import dplyr -#' @importFrom emmeans emmeans -#' @importFrom graphics pairs -#' @importFrom stats confint mad -#' -#' @export -get_contrasts.lmerModLmerTest <- function(fit, formula, adjust="tukey", ...) { - formula <- as.formula(paste0("~", formula)) - - - # emmeans --------------------------------------------------------------- - means <- fit %>% - emmeans::emmeans(formula) %>% - as.data.frame() %>% - dplyr::rename_( - "Mean" = "emmean", - "CI_lower" = "lower.CL", - "CI_higher" = "upper.CL" - ) - - - # Contrasts --------------------------------------------------------------- - contrasts <- fit %>% - emmeans::emmeans(formula) %>% - graphics::pairs(adjust = adjust) %>% - as.data.frame() %>% - dplyr::rename_( - "Contrast" = "contrast", - "Difference" = "estimate" - ) - - output <- list(means = means, contrasts = contrasts) - return(output) -} diff --git a/R/get_contrasts.stanreg.R b/R/get_contrasts.stanreg.R deleted file mode 100644 index 6b3bf4e..0000000 --- a/R/get_contrasts.stanreg.R +++ /dev/null @@ -1,124 +0,0 @@ -#' Compute estimated marginal means and contrasts from stanreg models. -#' -#' Compute estimated marginal means and contrasts from a stanreg models. -#' -#' @param fit A stanreg model. -#' @param formula A character vector (formula like format, i.e., including interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. -#' @param prob A numeric scalar in the interval (0,1) giving the target probability content of the intervals. The nominal probability content of the intervals is the multiple of 1/nrow(obj) nearest to prob. -#' @param ... Arguments passed to or from other methods. -#' -#' -#' @return list with estimated marginal means and contrasts. -#' -#' -#' @examples -#' \dontrun{ -#' library(psycho) -#' require(rstanarm) -#' fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season * Sex, data=affective) -#' -#' contrasts <- get_contrasts(fit, formula="Birth_Season * Sex") -#' contrasts$means -#' -#' contrasts <- get_contrasts(fit, formula="Birth_Season") -#' contrasts$contrasts -#' } -#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} -#' -#' @method get_contrasts stanreg -#' @import coda -#' @importFrom emmeans emmeans -#' @importFrom graphics pairs -#' @importFrom stats confint mad -#' -#' @export -get_contrasts.stanreg <- function(fit, formula, prob = 0.9, ROPE = FALSE, ROPE_bounds = NULL, ...) { - formula <- as.formula(paste0("~", formula)) - - - # emmeans --------------------------------------------------------------- - means_posterior <- fit %>% - emmeans::emmeans(formula, ...) %>% - emmeans::as.mcmc.emmGrid() %>% - as.matrix() %>% - coda::as.mcmc() %>% - as.data.frame() - - means <- data.frame() - - for (name in names(means_posterior)) { - var <- means_posterior[[name]] - - CI_values <- HDI(var, prob = prob) - CI_values <- c(CI_values$values$HDImin, CI_values$values$HDImax) - - var <- data.frame( - Level = name, - Median = median(var), - MAD = mad(var), - CI_lower = CI_values[seq(1, length(CI_values), 2)], - CI_higher = CI_values[seq(2, length(CI_values), 2)] - ) - - means <- rbind(means, var) - } - - - # Contrasts --------------------------------------------------------------- - contrasts_posterior <- fit %>% - emmeans::emmeans(formula, ...) %>% - graphics::pairs() %>% - emmeans::as.mcmc.emmGrid() %>% - as.matrix() %>% - coda::as.mcmc() %>% - as.data.frame() - - contrasts <- data.frame() - - if (ROPE == TRUE) { - if (!is.null(ROPE_bounds)) { - for (name in names(contrasts_posterior)) { - var <- contrasts_posterior[[name]] - - CI_values <- HDI(var, prob = prob) - CI_values <- c(CI_values$values$HDImin, CI_values$values$HDImax) - - var <- data.frame( - Contrast = stringr::str_remove(name, "contrast "), - Median = median(var), - MAD = mad(var), - CI_lower = CI_values[seq(1, length(CI_values), 2)], - CI_higher = CI_values[seq(2, length(CI_values), 2)], - MPE = mpe(var)$MPE, - ROPE = rope(var, ROPE_bounds)$rope_probability - ) - - contrasts <- rbind(contrasts, var) - } - output <- list(means = means, contrasts = contrasts) - return(output) - } else { - warning("you need to specify ROPE_bounds (e.g. 'c(-0.1, 0.1)'). ROPE is not computed.") - } - } - - for (name in names(contrasts_posterior)) { - var <- contrasts_posterior[[name]] - - CI_values <- HDI(var, prob = prob) - CI_values <- c(CI_values$values$HDImin, CI_values$values$HDImax) - - var <- data.frame( - Contrast = stringr::str_remove(name, "contrast "), - Median = median(var), - MAD = mad(var), - CI_lower = CI_values[seq(1, length(CI_values), 2)], - CI_higher = CI_values[seq(2, length(CI_values), 2)], - MPE = mpe(var)$MPE - ) - - contrasts <- rbind(contrasts, var) - } - output <- list(means = means, contrasts = contrasts) - return(output) -} diff --git a/R/get_means.R b/R/get_means.R new file mode 100644 index 0000000..c9f9f42 --- /dev/null +++ b/R/get_means.R @@ -0,0 +1,152 @@ +#' Compute estimated means from models. +#' +#' Compute estimated means of factor levels based on a fitted model. +#' +#' @param fit A model (lm, lme4 or rstanarm). +#' @param formula A character vector (formula like format, i.e., including +#' interactions or nesting terms) specifying the names of the predictors over which EMMs are desired. +#' @param CI Determine the confidence or credible interval bounds. +#' @param ... Arguments passed to or from other methods. For instance, transform="response". +#' +#' +#' @return Estimated means (or median of means for Bayesian models) +#' +#' +#' @examples +#' \dontrun{ +#' library(psycho) +#' require(lmerTest) +#' require(rstanarm) +#' +#' +#' fit <- glm(Sex ~ Birth_Season, data=affective, family="binomial") +#' get_means(fit) +#' +#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1|Salary), data=affective) +#' get_means(fit, formula="Birth_Season") +#' +#' fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data=affective) +#' get_means(fit, formula="Birth_Season") +#' +#' } +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @export +get_means <- function(fit, formula=NULL, CI=90, ...) { + UseMethod("get_means") +} + + +#' @method get_means stanreg +#' @export +get_means.stanreg <- function(fit, formula=NULL, CI=90, ...){ + .get_means_bayes(fit, formula, CI, ...) +} + +#' @method get_means lm +#' @export +get_means.lm <- function(fit, formula=NULL, CI=95, ...){ + .get_means_freq(fit, formula, CI, ...) +} + +#' @method get_means glm +#' @export +get_means.glm <- function(fit, formula=NULL, CI=95, ...){ + .get_means_freq(fit, formula, CI, ...) +} + +#' @method get_means lmerModLmerTest +#' @export +get_means.lmerModLmerTest <- function(fit, formula=NULL, CI=95, ...){ + .get_means_freq(fit, formula, CI, ...) +} + +#' @method get_means glmerMod +#' @export +get_means.glmerMod <- function(fit, formula=NULL, CI=95, ...){ + .get_means_freq(fit, formula, CI, ...) +} + +#' @method get_means lmerMod +#' @export +get_means.lmerMod <- function(fit, formula=NULL, CI=95, ...){ + .get_means_freq(fit, formula, CI, ...) +} + + + + +#' @import dplyr +#' @importFrom emmeans emmeans +#' @importFrom stats confint mad +#' @keywords internal +.get_means_bayes <- function(fit, formula=NULL, CI=90, ...) { + + if(is.null(formula)){ + formula <- paste(get_info(fit)$predictors, collapse=" * ") + } + + if(is.character(formula)){ + formula <- as.formula(paste0("~ ", formula)) + } + + # Means --------------------------------------------------------------- + means_posterior <- fit %>% + emmeans::emmeans(formula) %>% + emmeans::as.mcmc.emmGrid() %>% + as.matrix() %>% + as.data.frame() + + means <- data.frame() + + for (name in names(means_posterior)) { + var <- means_posterior[[name]] + + CI_values <- HDI(var, prob = CI/100) + CI_values <- c(CI_values$values$HDImin, CI_values$values$HDImax) + + var <- data.frame( + Level = name, + Median = median(var), + MAD = mad(var), + CI_lower = CI_values[seq(1, length(CI_values), 2)], + CI_higher = CI_values[seq(2, length(CI_values), 2)] + ) + + means <- rbind(means, var) + } + + return(means) +} + + + + +#' @import dplyr +#' @importFrom emmeans emmeans +#' @importFrom stats confint +#' @keywords internal +.get_means_freq <- function(fit, formula=NULL, CI=95, ...) { + + if(is.null(formula)){ + formula <- paste(get_info(fit)$predictors, collapse=" * ") + } + + if(is.character(formula)){ + formula <- as.formula(paste0("~ ", formula)) + } + + # Means --------------------------------------------------------------- + means <- fit %>% + emmeans::emmeans(formula, ...) %>% + confint(CI/100) %>% + as.data.frame() + + names(means) <- stringr::str_replace(names(means), "emmean", "Mean") + names(means) <- stringr::str_replace(names(means), "lower.CL", "CI_lower") + names(means) <- stringr::str_replace(names(means), "upper.CL", "CI_upper") + names(means) <- stringr::str_replace(names(means), "asymp.LCL", "CI_lower") + names(means) <- stringr::str_replace(names(means), "asymp.UCL", "CI_upper") + + return(means) +} diff --git a/docs/~$index.html b/docs/~$index.html new file mode 100644 index 0000000000000000000000000000000000000000..dbf56053ba1df5f78a217c172771146e9a6dab72 GIT binary patch literal 162 zcmd;d@lDLmFE7r{WFP@>GPp4KG9)r&GvqUrGZX`9i1tepUf*G`Vd&V9bbgisBLf4B ph8cZj!pl1hwhSE?pz<&pCVy>$_#Fm2hAu9KD4@wD45% + ggplot(aes(x=Level, y=Median, group=1)) + geom_line() + geom_pointrange(aes(ymin=CI_lower, ymax=CI_higher)) + ylab("Life Satisfaction") + diff --git a/vignettes/bayesian.Rmd b/vignettes/bayesian.Rmd index e870d5a..b4f4a44 100644 --- a/vignettes/bayesian.Rmd +++ b/vignettes/bayesian.Rmd @@ -251,25 +251,22 @@ print(results) What interest us is the pairwise comparison between the groups. The `get_contrasts` function computes the estimated marginal means (least-squares means), *i.e.*, the means of each group estimated by the model, as well as the contrasts. -```{r, message=FALSE, results="hide"} -contrasts <- psycho::get_contrasts(fit, "Salary") -``` -We can see the estimated means like that: +We can see the estimated means (in fact, the median of the posterior distribution of the estimated means) like that: ```{r echo=T, message=FALSE, warning=FALSE, results='hide'} -contrasts$means +psycho::get_means(fit) ``` ```{r echo=FALSE, message=FALSE, warning=FALSE} -kable(contrasts$means, digits=2) +kable(psycho::get_means(fit), digits=2) ``` And the contrasts comparisons like that: ```{r echo=T, message=FALSE, warning=FALSE, results='hide'} -contrasts$contrasts +psycho::get_contrasts(fit) ``` ```{r echo=FALSE, message=FALSE, warning=FALSE} -kable(contrasts$contrasts, digits=2) +kable(psycho::get_contrasts(fit), digits=2) ``` As we can see, the only probable difference (MPE > 90%) is between **Salary <1000** and **Salary 2000+**. @@ -277,7 +274,8 @@ As we can see, the only probable difference (MPE > 90%) is between **Salary <100 ### Model Visualization ```{r, fig.width=7, fig.height=4.5, eval = TRUE, results='markup', fig.align='center', comment=NA} -ggplot(contrasts$means, aes(x=Level, y=Median, group=1)) + +psycho::get_means(fit) %>% + ggplot(aes(x=Level, y=Median, group=1)) + geom_line() + geom_pointrange(aes(ymin=CI_lower, ymax=CI_higher)) + ylab("Life Satisfaction") + diff --git a/vignettes/bayesian.html b/vignettes/bayesian.html index 8009e57..d2da91a 100644 --- a/vignettes/bayesian.html +++ b/vignettes/bayesian.html @@ -12,11 +12,11 @@ - + Bayesian Analysis in Psychology - + @@ -88,7 +88,7 @@

Bayesian Analysis in Psychology

Dominique Makowski

-

2018-08-29

+

2018-10-18

Abstract

Why use frequentist methods when you can use, in an even simpler way, the Bayesian framework? Throughout this tutorial, we will explore many of the analyses you might want to do with your data.

@@ -256,10 +256,10 @@

Model Exploration

(Intercept) -4.06 -0.16 -3.80 -4.30 +4.07 +0.15 +3.82 +4.31 NA NA @@ -268,7 +268,7 @@

Model Exploration

0.19 0.04 0.13 -0.24 +0.25 100 0.8 @@ -290,9 +290,9 @@

Model Exploration

## ~ normal (location = (0), scale = (3.11)) ## ## -## The model has an explanatory power (R2) of about 2.31% (MAD = 0.0089, 90% CI [0.010, 0.037], adj. R2 = 0.020). The intercept is at 4.06 (MAD = 0.16, 90% CI [3.80, 4.30]). Within this model: +## The model has an explanatory power (R2) of about 2.29% (MAD = 0.0082, 90% CI [0.0098, 0.036], adj. R2 = 0.020). The intercept is at 4.07 (MAD = 0.15, 90% CI [3.82, 4.31]). Within this model: ## -## - The effect of Tolerating has a probability of 100% of being positive (Median = 0.19, MAD = 0.037, 90% CI [0.13, 0.24], Overlap = 0.80%). +## - The effect of Tolerating has a probability of 100% of being positive (Median = 0.19, MAD = 0.035, 90% CI [0.13, 0.25], Overlap = 0.80%).

Note that the print() returns also additional info, such as the 100% CI of the R2 and, for each parameter, the limits of the range defined by the MPE.

@@ -301,7 +301,7 @@

Interpretation

Full Bayesian mixed linear models are fitted using the rstanarm R wrapper for the stan probabilistic language (Gabry & Goodrich, 2016). Bayesian inference was done using Markov Chain Monte Carlo (MCMC) sampling. The prior distributions of all effects were set as weakly informative (mean = 0, SD = 3.11), meaning that we did not expect effects different from null in any particular direction. For each model and each coefficient, we will present several characteristics of the posterior distribution, such as its median (a robust estimate comparable to the beta from frequentist linear models), MAD (median absolute deviation, a robust equivalent of standard deviation) and the 90% credible interval. Instead of the p value as an index of effect existence, we also computed the maximum probability of effect (MPE), i.e., the maximum probability that the effect is different from 0 in the median’s direction. For our analyses, we will consider an effect as inconsistent (i.e., not probable enough) if its MPE is lower than 90% (however, beware not to fall in a p value-like obsession).

-

The current model explains about 2.31% of life satisfaction variance. Within this model, a positive linear relationship between life satisfaction and tolerating exists with high probability (Median = 0.19, MAD = 0.037, 90% CI [0.13, 0.24], MPE = 100%).

+

The current model explains about 2.29% of life satisfaction variance. Within this model, a positive linear relationship between life satisfaction and tolerating exists with high probability (Median = 0.19, MAD = 0.035, 90% CI [0.13, 0.25], MPE = 100%).

Model Visualization

@@ -324,63 +324,63 @@

Model Visualization

0.500000 -4.153399 -3.932312 -4.368151 +4.158432 +3.949179 +4.384088 1.222222 -4.291112 -4.119562 -4.477574 +4.293857 +4.115526 +4.474025 1.944444 -4.427491 -4.288660 -4.573628 +4.430605 +4.283335 +4.565502 2.666667 -4.565089 -4.457880 -4.672556 +4.566415 +4.459957 +4.672896 3.388889 -4.700749 -4.617500 -4.775216 +4.702832 +4.624741 +4.781100 4.111111 -4.837712 -4.774447 -4.904865 +4.839442 +4.771831 +4.903746 4.833333 -4.974317 -4.897483 -5.048027 +4.976131 +4.899352 +5.051889 5.555556 -5.111513 -5.012715 -5.217985 +5.112023 +5.006924 +5.212763 6.277778 -5.247626 -5.111737 -5.384486 +5.249172 +5.110702 +5.388208 7.000000 -5.384336 -5.204701 -5.549050 +5.384481 +5.218598 +5.569687 @@ -390,7 +390,7 @@

Model Visualization

geom_ribbon(aes(ymin=Life_Satisfaction_CI_5, ymax=Life_Satisfaction_CI_95), alpha=0.1)
-

+

@@ -411,17 +411,16 @@

Model Exploration

## ~ normal (location = (0, 0), scale = (3.61, 3.61)) ## ## -## The model has an explanatory power (R2) of about 0.43% (MAD = 0.0038, 90% CI [0, 0.011], adj. R2 = -0.0038). The intercept is at 4.76 (MAD = 0.064, 90% CI [4.66, 4.87]). Within this model: +## The model has an explanatory power (R2) of about 0.41% (MAD = 0.0036, 90% CI [0, 0.011], adj. R2 = -0.0036). The intercept is at 4.77 (MAD = 0.065, 90% CI [4.66, 4.87]). Within this model: ## -## - The effect of Salary<2000 has a probability of 86.33% of being positive (Median = 0.13, MAD = 0.12, 90% CI [-0.071, 0.31], Overlap = 59.15%). -## - The effect of Salary2000+ has a probability of 92.85% of being positive (Median = 0.20, MAD = 0.14, 90% CI [-0.028, 0.42], Overlap = 47.25%). +## - The effect of Salary<2000 has a probability of 86.02% of being positive (Median = 0.12, MAD = 0.12, 90% CI [-0.065, 0.31], Overlap = 59.60%). +## - The effect of Salary2000+ has a probability of 91.85% of being positive (Median = 0.20, MAD = 0.14, 90% CI [-0.041, 0.43], Overlap = 49.04%).

Post-hoc / Contrasts / Comparisons

What interest us is the pairwise comparison between the groups. The get_contrasts function computes the estimated marginal means (least-squares means), i.e., the means of each group estimated by the model, as well as the contrasts.

-
contrasts <- psycho::get_contrasts(fit, "Salary")
-

We can see the estimated means like that:

-
contrasts$means
+

We can see the estimated means (in fact, the median of the posterior distribution of the estimated means) like that:

+
psycho::get_means(fit)
@@ -435,7 +434,7 @@

Post-hoc / Contrasts / Comparisons

- + @@ -445,19 +444,19 @@

Post-hoc / Contrasts / Comparisons

- + - + - +
Salary <10004.764.77 0.06 4.66 4.87 4.89 0.10 4.745.055.06
Salary 2000+ 4.970.120.13 4.765.175.18

And the contrasts comparisons like that:

-
contrasts$contrasts
+
psycho::get_contrasts(fit)
@@ -472,27 +471,27 @@

Post-hoc / Contrasts / Comparisons

- + - + - - - + + + - - - - + + + +
<1000 - <2000-0.13-0.12 0.12 -0.31 0.0786.3386.02
<1000 - 2000+ -0.20 0.14-0.420.0392.85-0.430.0491.85
<2000 - 2000+ -0.070.15-0.330.1867.800.16-0.340.1967.30
@@ -500,12 +499,13 @@

Post-hoc / Contrasts / Comparisons

Model Visualization

-
ggplot(contrasts$means, aes(x=Level, y=Median, group=1)) +
+
psycho::get_means(fit) %>% 
+  ggplot(aes(x=Level, y=Median, group=1)) +
   geom_line() +
   geom_pointrange(aes(ymin=CI_lower, ymax=CI_higher)) +
   ylab("Life Satisfaction") +
   xlab("Salary")
-

+

@@ -539,16 +539,16 @@

Model Exploration

0.01 0.01 0.00 -0.02 +0.03 NA NA (Intercept) --2.21 -0.22 --2.55 --1.86 +-2.20 +0.23 +-2.56 +-1.84 NA NA @@ -559,7 +559,7 @@

Model Exploration

0.13 0.29 100 -3.03 +4.05 @@ -582,7 +582,7 @@

Model Visualization

ymax=Sex_CI_95), alpha=0.1) + ylab("Probability of being a male")
-

+

We can nicely see the non-linear relationship between adjusting and the probability of being a male.

@@ -624,8 +624,8 @@

Model Exploration

(Intercept) 5.19 -0.12 -4.99 +0.11 +5.00 5.39 NA NA @@ -636,26 +636,26 @@

Model Exploration

0.03 -0.15 -0.05 -99.85 -12.4 +99.90 +10.73 SexM -0.65 -0.31 --1.14 --0.12 -98.38 -30.2 +0.30 +-1.18 +-0.15 +98.17 +30.16 Concealing:SexM 0.18 0.07 -0.07 -0.29 -99.48 -21.2 +0.06 +0.30 +99.52 +21.39 @@ -684,142 +684,142 @@

Model Visualization

0.0000000 F -5.185290 -4.994448 -5.394204 +5.191753 +5.004764 +5.387830 0.7777778 F -5.109559 -4.962070 -5.287253 +5.115006 +4.955505 +5.268164 1.5555556 F -5.035789 -4.913544 -5.170142 +5.038884 +4.910601 +5.160755 2.3333333 F -4.960510 -4.868786 -5.065206 +4.963292 +4.865873 +5.057979 3.1111111 F -4.886170 -4.811681 -4.969734 +4.886690 +4.811077 +4.964710 3.8888889 F -4.811196 -4.737916 -4.888468 +4.810828 +4.734399 +4.882474 4.6666667 F -4.737273 -4.645381 -4.826462 +4.734997 +4.647659 +4.825009 5.4444444 F -4.661839 -4.544478 -4.778555 +4.658941 +4.548787 +4.781096 6.2222222 F -4.586476 -4.438806 -4.739371 +4.582078 +4.438112 +4.734427 7.0000000 F -4.510915 -4.328438 -4.701083 +4.506438 +4.331434 +4.695987 0.0000000 M -4.529505 -4.064161 -5.023550 +4.540271 +4.062365 +5.007913 0.7777778 M -4.591087 -4.178192 -4.985134 +4.599483 +4.190075 +4.982253 1.5555556 M -4.654500 -4.315886 -4.970058 +4.661595 +4.336947 +4.977431 2.3333333 M -4.719024 -4.453410 -4.966347 +4.723778 +4.477748 +4.983064 3.1111111 M -4.782819 -4.586485 -4.973848 +4.787592 +4.580817 +4.965151 3.8888889 M -4.846589 -4.688004 -5.000359 +4.848263 +4.695615 +5.001104 4.6666667 M -4.907982 -4.755944 -5.056011 +4.908898 +4.754656 +5.063536 5.4444444 M -4.971559 -4.791620 -5.165991 +4.971262 +4.784225 +5.165571 6.2222222 M -5.031855 -4.782992 -5.278818 +5.033359 +4.782007 +5.279740 7.0000000 M -5.095438 -4.774944 -5.410334 +5.096161 +4.798007 +5.432951 @@ -831,7 +831,7 @@

Model Visualization

ymax=Life_Satisfaction_CI_95), alpha=0.1) + ylab("Life Satisfaction") -

+

We can see that the error for the males is larger, due to less observations.

@@ -956,10 +956,10 @@

Model Exploration

(Intercept) -4.99 -0.55 -4.15 -5.87 +5.03 +0.45 +4.26 +5.75 NA NA @@ -968,9 +968,9 @@

Model Exploration

-0.07 0.03 -0.11 --0.02 -99.6 -26.90 +-0.03 +99.4 +18.09 poly(Age, 2, raw = TRUE)2 @@ -978,8 +978,8 @@

Model Exploration

0.00 0.00 0.00 -98.8 -79.91 +99.0 +79.36 @@ -998,7 +998,7 @@

Model Visualization

geom_ribbon(aes(ymin=Concealing_CI_5, ymax=Concealing_CI_95), alpha=0.1) -

+

As we can see, adding the polynomial degree changes the relationship. Since the model is here very simple, we can add on the plot the actual points (however, they do not take into account the random effects and such), as well as plot the two models. Also, let’s make it “dynamic” using plotly.

p <- ggplot() +
   # Linear model
@@ -1028,8 +1028,8 @@ 

Model Visualization

library(plotly) # To create interactive plots ggplotly(p) # To transform a ggplot into an interactive plot
-
- +
+

It’s good to take a few steps back and look at the bigger picture :)

@@ -1100,7 +1100,7 @@

Weakly informative priors

geom_density(aes(x=posterior), fill="lightblue", alpha=0.5) + geom_density(aes(x=prior), fill="blue", alpha=0.5) + scale_y_sqrt() # Change the Y axis so the plot is less ugly -

+

This plot is rather ugly, because our posterior is very precise (due to the large sample) compared to the prior.

@@ -1133,7 +1133,7 @@

Plot all iterations

geom_line(aes(y=Iteration_Value, group=Iteration), size=0.3, alpha=0.01) + geom_line(aes(y=Sex_Median), size=1) + ylab("Male Probability\n")
-

+

diff --git a/vignettes/bayesian.knit.md b/vignettes/bayesian.knit.md deleted file mode 100644 index 7905df1..0000000 --- a/vignettes/bayesian.knit.md +++ /dev/null @@ -1,812 +0,0 @@ ---- -title: "Bayesian Analysis in Psychology" -output: - rmarkdown::html_vignette: - toc: true -author: -- Dominique Makowski -date: "2018-08-29" -tags: [r, psychology, neuroscience] -abstract: | - Why use frequentist methods when you can use, in an even simpler way, the Bayesian framework? Throughout this tutorial, we will explore many of the analyses you might want to do with your data. -vignette: > - %\VignetteIndexEntry{BayesianPsychology} - %\VignetteDepends{dplyr} - %\VignetteDepends{tidyr} - %\VignetteDepends{ggplot2} - %\VignetteDepends{plotly} - \usepackage[utf8]{inputenc} - %\VignetteEngine{knitr::rmarkdown} -editor_options: - chunk_output_type: console ---- - - - ------- - - - - -## The Bayesian Framework - -### Why use the Bayesian Framework? - -In short, because it's: - -- Better -- Simpler -- Superior -- Preferable -- More appropriate -- More desirable -- More useful -- More valuable - -##### **From Makowski et al. (*under review*):** - -> Reasons to prefer this approach are reliability, better accuracy in noisy data, better estimation for small samples, less prone to type I error, the possibility of introducing prior knowledge into the analysis and, critically, results intuitiveness and their straightforward interpretation (Andrews & Baguley, 2013; Etz & Vandekerckhove, 2016; Kruschke, 2010; Kruschke, Aguinis, & Joo, 2012; Wagenmakers et al., 2018). Indeed, in the frequentist view, the effects are fixed (but unknown) and data are random, while the Bayesian inference calculates the probability of different effect values (called the **"posterior" distribution**) given the observed data. Bayesian’s uncertainty can be summarized, for example, by giving a range of values on the posterior distribution that includes 95% of the probability (the 95% *Credible Interval*). To illustrate the difference, the Bayesian framework allows to say "*given the observed data, the effect has 95% probability of falling within this range*", while the Frequentist less straightforward alternative would be "*there is a 95% probability that when computing a confidence interval from data of this sort, the effect falls within this range*". In general, the frequentist approach has been associated with the focus on null hypothesis testing, and the misuse of *p* values has been shown to critically contribute to the reproducibility crisis of psychological science (Chambers, Feredoes, Muthukumaraswamy, Suresh, & Etchells, 2014; Szucs & Ioannidis, 2016). There is a general agreement that the generalization of the Bayesian approach is a way of overcoming these issues (Benjamin et al., 2018; Etz & Vandekerckhove, 2016). - -### What is the Bayesian Framework? - -Once we agreed that the Bayesian framework is the right way to go, you might wonder what is the Bayesian framework. **What's all the fuss about?** - -Omitting the maths behind it, let's just say that: - -- The frequentist guy tries to estimate "the real effect". The "real" value of the correlation between X and Y. It returns a "point-estimate" (*i.e.*, a single value) of the "real" correlation (*e.g.*, r = 0.42), considering that the data is sampled at random from a "parent", usually normal distribution of data. -- **The Bayesian master assumes no such thing**. The data are what they are. Based on this observed data (and eventually from its expectations), the Bayesian sampling algorithm will return a probability distribution of the effect that is compatible with the observed data. For the correlation between X and Y, it will return a distribution that says "the most probable effect is 0.42, but this data is also compatible with correlations of 0.12 or 0.74". -- To characterize our effects, **no need of p values** or other mysterious indices. We simply describe the posterior distribution (*i.e.*, the distribution of the effect). We can present the median (better than the mean, as it actually means that the effect has 50% of chance of being higher and 50% of chance of being lower), the MAD (a median-based, robust equivalent of SD) and other stuff such as the 90% HDI, called here *credible interval*. - - -### The "Posterior" distribution - - - -Let's imagine two numeric variables, Y and X. The correlation between them is r = -0.063 (p < .05). A Bayesian analysis would return the probability of distribution of this effect (the **posterior**), that we can characterize using several indices (centrality (**median** or mean), dispersion (SD or Median Absolute Deviation - **MAD**), etc.). Let's plot the posterior distribution of the possible correlation values that are compatible with our data. - -
-Posterior probability distribution of the correlation between X and Y -

Posterior probability distribution of the correlation between X and Y

-
- -In this example (based on real data): - -- The **median of the posterior distribution is really close to the *r* coefficient obtained through a "normal" correlation analysis**, appearing as a good point-estimate of the correlation. Moreover, and unlike the frequentist estimate, the median has an intuitive meaning (as it cuts the distribution in two equal parts): the "true" effect has 50% of chance of being higher and 50% of chance of being lower. -- We can also compute the **90% *credible* interval**, which shows where the true effect can fall with a probability of 90% (better than 95% CI, see *Kruschke, 2015*). -- Finally, we can also compute the **MPE**, *i.e.*, the maximum probability of effect, which is the probability that the effect is in the median's direction (*i.e.*, negative in this example): the area in red. It interesting to note that the probability that the effect is opposite ((100 - MPE) / 100, here (100-98.85) / 100 = 0.012) is relatively close to the actual **p value** obtained through frequentist correlation (p = 0.025). - -**Now that you're familiar with posterior distributions, the core difference of the Bayesian framework, let's practice!** - -## The affective Dataset - -Let's start by taking a look at the dataset included within the `psycho` package. - - -```r -library(rstanarm) -library(dplyr) -library(ggplot2) -library(psycho) - -df <- psycho::affective -summary(df) -``` - - -``` -## Sex Age Birth_Season Salary Life_Satisfaction -## F:1000 Min. :18.00 Fall :288 <1000:514 Min. :1.000 -## M: 251 1st Qu.:21.16 Spring:348 <2000:223 1st Qu.:4.000 -## Median :22.97 Summer:332 2000+:128 Median :5.000 -## Mean :26.91 Winter:283 NA's :386 Mean :4.847 -## 3rd Qu.:27.54 3rd Qu.:6.000 -## Max. :80.14 Max. :7.000 -## Concealing Adjusting Tolerating -## Min. :0.000 Min. :0.000 Min. :0.500 -## 1st Qu.:2.750 1st Qu.:2.750 1st Qu.:3.500 -## Median :3.750 Median :3.750 Median :4.250 -## Mean :3.743 Mean :3.802 Mean :4.157 -## 3rd Qu.:4.750 3rd Qu.:5.000 3rd Qu.:5.000 -## Max. :7.000 Max. :6.750 Max. :7.000 -``` - -The data include **5 continuous variables** (age, life satisfaction and 3 affective styles) and **3 factors** (sex, salary and season of birth). - - - -## Simple Regression (*Correlation*) - -Let's start with something simple : a **correlation**. To simplify, a (Pearson's) correlation is pretty much nothing more than a simple linear regression (with standardized variables). Let's see if there's a linear relationship between **Life Satisfaction** and the tendency of **Tolerating** our emotions using a Bayesian linear regression model. - -### Model Exploration - - -```r -# Let's fit our model -fit <- rstanarm::stan_glm(Life_Satisfaction ~ Tolerating, data=df) -``` - - - - -Let's check the results: - -```r -# Format the results using analyze() -results <- psycho::analyze(fit) - -# We can extract a formatted summary table -summary(results, round = 2) -``` - -Variable Median MAD CI_lower CI_higher MPE Overlap ------------- ------- ----- --------- ---------- ---- -------- -R2 0.02 0.01 0.01 0.04 NA NA -(Intercept) 4.06 0.16 3.80 4.30 NA NA -Tolerating 0.19 0.04 0.13 0.24 100 0.8 - -For each parameter of the model, the summary shows: - -- the **median** of the posterior distribution of the parameter (can be used as a point estimate, similar to the beta of frequentist models). -- the **Median Absolute Deviation (MAD)**, a robust measure of dispertion (could be seen as a robust version of SD). -- the **Credible Interval (CI)** (by default, the 90\% CI; see Kruschke, 2018), representing a range of possible parameter values. -- the **Maximum Probability of Effect (MPE)**, the probability that the effect is positive or negative (depending on the median’s direction). -- the **Overlap (O)**, the percentage of overlap between the posterior distribution and a normal distribution of mean 0 and same SD than the posterior. Can be interpreted as the probability that a value from the posterior distribution comes from a null distribution of same uncertainty (width). - -It also returns the (unadjusted) R2 (which represents the *percentage of variance of the outcome explained by the model*). In the Bayesian framework, the R2 is also estimated with probabilities. As such, characteristics of its posterior distribution are returned. - - - -We can also print a formatted version: - -```r -print(results) -``` - -``` -## We fitted a Markov Chain Monte Carlo gaussian (link = identity) model (4 chains, each with iter = 2000; warmup = 1000; thin = 1; post-warmup = 1000) to predict Life_Satisfaction (formula = Life_Satisfaction ~ Tolerating). The model's priors were set as follows: -## -## ~ normal (location = (0), scale = (3.11)) -## -## -## The model has an explanatory power (R2) of about 2.31% (MAD = 0.0089, 90% CI [0.010, 0.037], adj. R2 = 0.020). The intercept is at 4.06 (MAD = 0.16, 90% CI [3.80, 4.30]). Within this model: -## -## - The effect of Tolerating has a probability of 100% of being positive (Median = 0.19, MAD = 0.037, 90% CI [0.13, 0.24], Overlap = 0.80%). -``` - -Note that the `print()` returns also additional info, such as the 100\% CI of the R2 and, for each parameter, the limits of the range defined by the MPE. - - - -### Interpretation - - -For now, omit the part dedicated to priors. We'll see it in the next chapters. Let's rather interpret the part related to effects. - -> Full Bayesian mixed linear models are fitted using the rstanarm R wrapper for the stan probabilistic language (Gabry & Goodrich, 2016). Bayesian inference was done using Markov Chain Monte Carlo (MCMC) sampling. The prior distributions of all effects were set as weakly informative (mean = 0, SD = 3.11), meaning that we did not expect effects different from null in any particular direction. For each model and each coefficient, we will present several characteristics of the posterior distribution, such as its median (a robust estimate comparable to the beta from frequentist linear models), MAD (median absolute deviation, a robust equivalent of standard deviation) and the 90% credible interval. Instead of the *p value* as an index of effect existence, we also computed the maximum probability of effect (MPE), *i.e.*, the maximum probability that the effect is different from 0 in the median’s direction. For our analyses, we will consider an effect as inconsistent (*i.e.*, not probable enough) if its MPE is lower than 90% (however, **beware not to fall in a *p* value-like obsession**). - - -The current model explains about 2.31% of life satisfaction variance. Within this model, a positive linear relationship between life satisfaction and tolerating exists with high probability (Median = 0.19, MAD = 0.037, 90% CI [0.13, 0.24], MPE = 100%). - -### Model Visualization - -To visualize the model, the most neat way is to extract a "reference grid" (*i.e.*, a theorethical dataframe with balanced data). - - -```r -refgrid <- df %>% - select(Tolerating) %>% - psycho::refdata(length.out=10) - -predicted <- psycho::get_predicted(fit, newdata=refgrid) -``` - -```r -predicted -``` - - - - Tolerating Life_Satisfaction_Median Life_Satisfaction_CI_5 Life_Satisfaction_CI_95 ------------ ------------------------- ----------------------- ------------------------ - 0.500000 4.153399 3.932312 4.368151 - 1.222222 4.291112 4.119562 4.477574 - 1.944444 4.427491 4.288660 4.573628 - 2.666667 4.565089 4.457880 4.672556 - 3.388889 4.700749 4.617500 4.775216 - 4.111111 4.837712 4.774447 4.904865 - 4.833333 4.974317 4.897483 5.048027 - 5.555556 5.111513 5.012715 5.217985 - 6.277778 5.247626 5.111737 5.384486 - 7.000000 5.384336 5.204701 5.549050 - -Our refgrid is made of equally spaced (balanced) predictor values. It also include the median of the posterior prediction, as well as 90% credible intervals. Now, we can plot it as follows: - - -```r -ggplot(predicted, aes(x=Tolerating, y=Life_Satisfaction_Median)) + - geom_line() + - geom_ribbon(aes(ymin=Life_Satisfaction_CI_5, - ymax=Life_Satisfaction_CI_95), - alpha=0.1) -``` - - - - -## Regression with Categorical Predictor (*ANOVA*) - -When the predictor is categorical, simplifying the model is called running an ANOVA. Let's do it by answering the following question: does the level of **life satisfaction** depend on the salary? - -### Model Exploration - - -```r -# Let's fit our model -fit <- rstanarm::stan_glm(Life_Satisfaction ~ Salary, data=df) -``` -Let's check the results: - -```r -# Format the results using analyze() -results <- psycho::analyze(fit) - -# We can extract a formatted summary table -print(results) -``` - -``` -## We fitted a Markov Chain Monte Carlo gaussian (link = identity) model (4 chains, each with iter = 2000; warmup = 1000; thin = 1; post-warmup = 1000) to predict Life_Satisfaction (formula = Life_Satisfaction ~ Salary). The model's priors were set as follows: -## -## ~ normal (location = (0, 0), scale = (3.61, 3.61)) -## -## -## The model has an explanatory power (R2) of about 0.43% (MAD = 0.0038, 90% CI [0, 0.011], adj. R2 = -0.0038). The intercept is at 4.76 (MAD = 0.064, 90% CI [4.66, 4.87]). Within this model: -## -## - The effect of Salary<2000 has a probability of 86.33% of being positive (Median = 0.13, MAD = 0.12, 90% CI [-0.071, 0.31], Overlap = 59.15%). -## - The effect of Salary2000+ has a probability of 92.85% of being positive (Median = 0.20, MAD = 0.14, 90% CI [-0.028, 0.42], Overlap = 47.25%). -``` - -### Post-hoc / Contrasts / Comparisons - -What interest us is the pairwise comparison between the groups. The `get_contrasts` function computes the estimated marginal means (least-squares means), *i.e.*, the means of each group estimated by the model, as well as the contrasts. - - -```r -contrasts <- psycho::get_contrasts(fit, "Salary") -``` - -We can see the estimated means like that: - -```r -contrasts$means -``` - -Level Median MAD CI_lower CI_higher -------------- ------- ----- --------- ---------- -Salary <1000 4.76 0.06 4.66 4.87 -Salary <2000 4.89 0.10 4.74 5.05 -Salary 2000+ 4.97 0.12 4.76 5.17 - - -And the contrasts comparisons like that: - -```r -contrasts$contrasts -``` - -Contrast Median MAD CI_lower CI_higher MPE --------------- ------- ----- --------- ---------- ------ -<1000 - <2000 -0.13 0.12 -0.31 0.07 86.33 -<1000 - 2000+ -0.20 0.14 -0.42 0.03 92.85 -<2000 - 2000+ -0.07 0.15 -0.33 0.18 67.80 - -As we can see, the only probable difference (MPE > 90%) is between **Salary <1000** and **Salary 2000+**. - -### Model Visualization - - -```r -ggplot(contrasts$means, aes(x=Level, y=Median, group=1)) + - geom_line() + - geom_pointrange(aes(ymin=CI_lower, ymax=CI_higher)) + - ylab("Life Satisfaction") + - xlab("Salary") -``` - - - - -## Logistic Regressions - -Let's see if we can **predict the sex** with the tendency to flexibly *adjust* our emotional reactions. As the Sex is a binary factor (with two modalities), we have to fit a logistic model. - -### Model Exploration - - -```r -# Let's fit our model -fit <- rstanarm::stan_glm(Sex ~ Adjusting, data=df, family = "binomial") -``` - - - -First, let's check our model: - -```r -# Format the results using analyze() -results <- psycho::analyze(fit) - -# We can extract a formatted summary table -summary(results, round = 2) -``` - -Variable Median MAD CI_lower CI_higher MPE Overlap ------------- ------- ----- --------- ---------- ---- -------- -R2 0.01 0.01 0.00 0.02 NA NA -(Intercept) -2.21 0.22 -2.55 -1.86 NA NA -Adjusting 0.21 0.05 0.13 0.29 100 3.03 - -It appears that the link between adjusting and the sex is highly probable (MPE > 90%). But in what direction? To know that, we have to find out what is the intercept (the reference level). - - - -``` -## [1] "F" "M" -``` -As **female** is the first level, it means that it is the intercept. Based on our model, an increase of 1 on the scale of **adjusting** will increase the probability (expressed in log odds ratios) of being a **male**. - -### Model Visualization - -To visualize this type of model, we have to derive a reference grid. - - -```r -refgrid <- df %>% - select(Adjusting) %>% - psycho::refdata(length.out=10) - -predicted <- psycho::get_predicted(fit, newdata=refgrid) -``` - -Note that `get_predicted` automatically transformed log odds ratios (the values in which the model is expressed) to probabilities, easier to apprehend. - - -```r -ggplot(predicted, aes(x=Adjusting, y=Sex_Median)) + - geom_line() + - geom_ribbon(aes(ymin=Sex_CI_5, - ymax=Sex_CI_95), - alpha=0.1) + - ylab("Probability of being a male") -``` - - - -We can nicely see the non-linear relationship between adjusting and the probability of being a male. - -## Multiple Regressions and MANOVAs / ANCOVAs - -Let's create models a bit more complex, mixing factors with numeric predictors, to see if the **life satisfaction** is related to the tendency to suppress, **conceal** the emotional reactions, and does this relationship depends on the **sex**. - -### Model Exploration - - -```r -# Let's fit our model -fit <- rstanarm::stan_glm(Life_Satisfaction ~ Concealing * Sex, data=df) -``` - - - -Let's check our model: - -```r -# Format the results using analyze() -results <- psycho::analyze(fit) - -# We can extract a formatted summary table -summary(results, round = 2) -``` - -Variable Median MAD CI_lower CI_higher MPE Overlap ----------------- ------- ----- --------- ---------- ------ -------- -R2 0.01 0.01 0.00 0.02 NA NA -(Intercept) 5.19 0.12 4.99 5.39 NA NA -Concealing -0.10 0.03 -0.15 -0.05 99.85 12.4 -SexM -0.65 0.31 -1.14 -0.12 98.38 30.2 -Concealing:SexM 0.18 0.07 0.07 0.29 99.48 21.2 - -Again, it is important to notice that the intercept (the baseline) corresponds here to **Concealing = 0** and **Sex = F**. As we can see next, there is, with high probability, a negative linear relationship between concealing (*for females only*) and life satisfaction. Also, at the (theorethical) intercept (when concealing = 0), the males have a lower life satisfaction. Finally, the interaction is also probable. This means that when the participant is a male, the relationship between concealing and life satisfaction is significantly different (increased by 0.17. In other words, we could say that the relationship is of -0.10+0.17=0.07 in men). - -### Model Visualization - -How to represent this type of models? Again, we have to generate a reference grid. - - -```r -refgrid <- df %>% - select(Concealing, Sex) %>% - psycho::refdata(length.out=10) - -predicted <- psycho::get_predicted(fit, newdata=refgrid) -predicted -``` - - Concealing Sex Life_Satisfaction_Median Life_Satisfaction_CI_5 Life_Satisfaction_CI_95 ------------ ---- ------------------------- ----------------------- ------------------------ - 0.0000000 F 5.185290 4.994448 5.394204 - 0.7777778 F 5.109559 4.962070 5.287253 - 1.5555556 F 5.035789 4.913544 5.170142 - 2.3333333 F 4.960510 4.868786 5.065206 - 3.1111111 F 4.886170 4.811681 4.969734 - 3.8888889 F 4.811196 4.737916 4.888468 - 4.6666667 F 4.737273 4.645381 4.826462 - 5.4444444 F 4.661839 4.544478 4.778555 - 6.2222222 F 4.586476 4.438806 4.739371 - 7.0000000 F 4.510915 4.328438 4.701083 - 0.0000000 M 4.529505 4.064161 5.023550 - 0.7777778 M 4.591087 4.178192 4.985134 - 1.5555556 M 4.654500 4.315886 4.970058 - 2.3333333 M 4.719024 4.453410 4.966347 - 3.1111111 M 4.782819 4.586485 4.973848 - 3.8888889 M 4.846589 4.688004 5.000359 - 4.6666667 M 4.907982 4.755944 5.056011 - 5.4444444 M 4.971559 4.791620 5.165991 - 6.2222222 M 5.031855 4.782992 5.278818 - 7.0000000 M 5.095438 4.774944 5.410334 - -As we can see, the reference grid is balanced in terms of factors and numeric predictors. Now, to plot this becomes very easy! - - - -```r -ggplot(predicted, aes(x=Concealing, y=Life_Satisfaction_Median, fill=Sex)) + - geom_line(aes(colour=Sex)) + - geom_ribbon(aes(fill=Sex, - ymin=Life_Satisfaction_CI_5, - ymax=Life_Satisfaction_CI_95), - alpha=0.1) + - ylab("Life Satisfaction") -``` - - - -We can see that the error for the males is larger, due to less observations. - - - -## Mixed Models - - -### Why use mixed-models? - -- **From Makowski et al. (*under review*):** - -> The Mixed modelling framework allows estimated effects to vary by group at lower levels while estimating population-level effects through the specification of fixed (explanatory variables) and random (variance components) effects. Outperforming traditional procedures such as repeated measures ANOVA (Kristensen & Hansen, 2004), these models are particularly suited to cases in which experimental stimuli are heterogeneous (e.g., images) as the item-related variance, in addition to the variance induced by participants, can be accounted for (Baayen, Davidson, & Bates, 2008; Magezi, 2015). Moreover, mixed models can handle unbalanced data, nested designs, crossed random effects and missing data. - -As for how to run this type of analyses, it is quite easy. Indeed, all what has been said previously remains the same for mixed models. Except that there are random effects (specified by putting `+ (1|random_term)` in the formula). For example, we might want to consider the **salary** as a random effect (to "**adjust**" (*so to speak*) for the fact that the data is structured in two groups). Let's explore the relationship between the tendency to **conceal** emotions and **age** (*adjusted* for **salary**). - -### Model Exploration - - -```r -# Let's fit our model (it takes more time) -fit <- rstanarm::stan_lmer(Concealing ~ Age + (1|Salary), data=df) -``` - - -Let's check our model: - -```r -# Format the results using analyze() -results <- psycho::analyze(fit) -``` - -``` -## Warning in ypredloo - y: la taille d'un objet plus long n'est pas multiple -## de la taille d'un objet plus court -``` - -```r -# We can extract a formatted summary table -summary(results, round = 2) -``` - -Variable Median MAD CI_lower CI_higher MPE Overlap ------------- ------- ----- --------- ---------- ----- -------- -R2 0.00 0.00 0.00 0.01 NA NA -(Intercept) 3.95 0.17 3.61 4.25 NA NA -Age -0.01 0.00 -0.02 0.00 91.2 46.61 - -As we can see, the linear relationship has only a moderate probability of being different from 0. - -### Model Visualization - - - -```r -refgrid <- df %>% - select(Age) %>% - psycho::refdata(length.out=10) - -# We name the predicted dataframe by adding '_linear' to keep it for further comparison (see next part) -predicted_linear <- psycho::get_predicted(fit, newdata=refgrid) -``` - -```r -ggplot(predicted_linear, aes(x=Age, y=Concealing_Median)) + - geom_line() + - geom_ribbon(aes(ymin=Concealing_CI_5, - ymax=Concealing_CI_95), - alpha=0.1) -``` - - - -## Polynomial Transformations - -Relationships in the real world are often non-linear. For example, based on the previous relationship between **concealing** and **age**, we could try modelling a polynomial (second order) transformation to the predictor. - -### Model Exploration - - -```r -# Let's fit our model (it takes more time) -fit <- rstanarm::stan_lmer(Concealing ~ poly(Age, 2, raw=TRUE) + (1|Salary), data=df) -``` - - -Let's check our model: - -```r -# Format the results using analyze() -results <- psycho::analyze(fit) -``` - -``` -## Warning in ypredloo - y: la taille d'un objet plus long n'est pas multiple -## de la taille d'un objet plus court -``` - -```r -# We can extract a formatted summary table -summary(results, round = 2) -``` - -Variable Median MAD CI_lower CI_higher MPE Overlap --------------------------- ------- ----- --------- ---------- ----- -------- -R2 0.01 0.01 0.00 0.02 NA NA -(Intercept) 4.99 0.55 4.15 5.87 NA NA -poly(Age, 2, raw = TRUE)1 -0.07 0.03 -0.11 -0.02 99.6 26.90 -poly(Age, 2, raw = TRUE)2 0.00 0.00 0.00 0.00 98.8 79.91 - -As we can see, both the linear relationship and the second order curvature are highly probable. However, when setting `raw=TRUE` in the formula, the coefficients become unintepretable. So let's visualize them. - -### Model Visualization - -The model visualization routine is similar to the previous ones. - - -```r -refgrid <- df %>% - select(Age) %>% - psycho::refdata(length.out=20) - -predicted_poly <- psycho::get_predicted(fit, newdata=refgrid) -``` - -```r -ggplot(predicted_poly, aes(x=Age, y=Concealing_Median)) + - geom_line() + - geom_ribbon(aes(ymin=Concealing_CI_5, - ymax=Concealing_CI_95), - alpha=0.1) -``` - - - -As we can see, adding the polynomial degree changes the relationship. Since the model is here very simple, we can add on the plot the actual points (however, they do not take into account the random effects and such), as well as plot the two models. Also, let's make it "dynamic" using `plotly`. - - -```r -p <- ggplot() + - # Linear model - geom_line(data=predicted_linear, - aes(x=Age, y=Concealing_Median), - colour="blue", - size=1) + - geom_ribbon(data=predicted_linear, - aes(x=Age, - ymin=Concealing_CI_5, - ymax=Concealing_CI_95), - alpha=0.1, - fill="blue") + - # Polynormial Model - geom_line(data=predicted_poly, - aes(x=Age, y=Concealing_Median), - colour="red", - size=1) + - geom_ribbon(data=predicted_poly, - aes(x=Age, - ymin=Concealing_CI_5, - ymax=Concealing_CI_95), - fill="red", - alpha=0.1) + - # Actual data - geom_point(data=df, aes(x=Age, y=Concealing)) - -library(plotly) # To create interactive plots -ggplotly(p) # To transform a ggplot into an interactive plot -``` - -
- - - -**It's good to take a few steps back and look at the bigger picture :)** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## Piors Specification - -One of the interesting aspect of the Bayesian framework is the possibility of adding prior expectations about the effect, to help model fitting and increase accuracy in noisy data or small samples. - - -### Weakly informative priors - -As you might have notice, we didn't specify any priors in the previous analyses. In fact, we let the algorithm define and set *weakly informative priors*, designed to provide moderate regularization and help stabilize computation, without biasing the effect direction. For example, a wealky informative prior, for a standardized predictor (with mean = 0 and SD = 1) could be a normal distribution with mean = 0 and SD = 1. This means that the effect of this predictor is expected to be equally probable in any direction (as the distribution is symmetric around 0), with probability being higher close to 0 and lower far from 0. - -While this prior doesn't bias the direction of the Bayesian (MCMC) sampling, it suggests that having an effect of 100 (*i.e.*, located at 100 SD of the mean as our variables are standardized) is highly unprobable, and that an effect close to 0 is more probable. - -To better play with priors, let's start by standardizing our dataframe. - - - -```r -# Standardize (scale and center) the numeric variables -dfZ <- psycho::standardize(df) -``` - -Then, we can explicitly specify a weakly informative prior for all effects of the model. - - -```r -# Let's fit our model -fit <- rstanarm::stan_glm(Life_Satisfaction ~ Tolerating, - data=dfZ, - prior=normal(location = 0, # Mean - scale = 1, # SD - autoscale=FALSE)) # Don't adjust scale automatically -``` - -Let's plot the prior (the expectation) against the posterior (the estimated effect) distribution. - - -```r -results <- psycho::analyze(fit) - -# Extract the posterior -posterior <- results$values$effects$Tolerating$posterior - -# Create a posterior with the prior and posterior distribution and plot them. -data.frame(posterior = posterior, - prior = rnorm(length(posterior), 0, 1)) %>% - ggplot() + - geom_density(aes(x=posterior), fill="lightblue", alpha=0.5) + - geom_density(aes(x=prior), fill="blue", alpha=0.5) + - scale_y_sqrt() # Change the Y axis so the plot is less ugly -``` - -![](bayesian_files/figure-html/unnamed-chunk-49-1.png) - - -This plot is rather ugly, because our posterior is very precise (due to the large sample) compared to the prior. - -### Informative priors - -Although the default priors tend to work well, prudent use of more informative priors is encouraged. It is important to underline that setting informative priors (**if realistic**), does not overbias the analysis. In other words, is only "directs" the sampling: if the data are highly informative about the parameter values (enough to overwhelm the prior), a prudent informative prior (even if oppositive to the observed effect) will yield similar results to a non-informative prior. **In other words, you can't change the results dramatically by tweaking the priors**. But as the amount of data and/or the signal-to-noise ratio decrease, using a more informative prior becomes increasingly important. Of course, if you see someone using a prior with mean = 42 and SD = 0.0001, you should look at his results with caution... - -Anyway, see the [official rstanarm documentation](https://CRAN.R-project.org/package=rstanarm/vignettes/priors.html) for details. - - - - - - - - -## Advanced Visualization - -### Plot all iterations - -As Bayesian models usually generate a lot of samples (*iterations*), one could want to plot them as well, instead (or along) the posterior "summary". This can be done quite easily by extracting all the iterations in `get_predicted`. - - -```r -# Fit the model -fit <- rstanarm::stan_glm(Sex ~ Adjusting, data=df, family = "binomial") -``` - -```r -# Generate a new refgrid -refgrid <- df %>% - select(Adjusting) %>% - psycho::refdata(length.out=10) - -# Get predictions and keep iterations -predicted <- psycho::get_predicted(fit, newdata=refgrid, keep_iterations=TRUE) - -# Reshape this dataframe to have iterations as factor -predicted <- predicted %>% - tidyr::gather(Iteration, Iteration_Value, starts_with("iter")) - -# Plot iterations as well as the median prediction -ggplot(predicted, aes(x=Adjusting)) + - geom_line(aes(y=Iteration_Value, group=Iteration), size=0.3, alpha=0.01) + - geom_line(aes(y=Sex_Median), size=1) + - ylab("Male Probability\n") -``` - - - - - - -## Credits - -This package helped you? Don't forget to cite the various packages you used :) - -You can cite `psycho` as follows: - -- Makowski, (2018). *The psycho Package: An Efficient and Publishing-Oriented Workflow for Psychological Science*. Journal of Open Source Software, 3(22), 470. https://doi.org/10.21105/joss.00470 - -## Contribution - -Improve this vignette by modifying [this](https://github.com/neuropsychology/psycho.R/blob/master/vignettes/bayesian.Rmd) file! From 7e48d49f7c082a632bd524c027025f3ef11bd8db Mon Sep 17 00:00:00 2001 From: Dominique Makowski Date: Thu, 18 Oct 2018 18:04:34 +0200 Subject: [PATCH 09/17] hotfix names of variables --- R/get_contrasts.R | 4 ++-- R/get_means.R | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/R/get_contrasts.R b/R/get_contrasts.R index d074de5..9ea4829 100644 --- a/R/get_contrasts.R +++ b/R/get_contrasts.R @@ -227,9 +227,9 @@ get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) "p" = "p.value" ) names(contrasts) <- stringr::str_replace(names(contrasts), "lower.CL", "CI_lower") - names(contrasts) <- stringr::str_replace(names(contrasts), "upper.CL", "CI_upper") + names(contrasts) <- stringr::str_replace(names(contrasts), "upper.CL", "CI_higher") names(contrasts) <- stringr::str_replace(names(contrasts), "asymp.LCL", "CI_lower") - names(contrasts) <- stringr::str_replace(names(contrasts), "asymp.UCL", "CI_upper") + names(contrasts) <- stringr::str_replace(names(contrasts), "asymp.UCL", "CI_higher") names(contrasts) <- stringr::str_replace(names(contrasts), "t.ratio", "t") names(contrasts) <- stringr::str_replace(names(contrasts), "z.ratio", "z") diff --git a/R/get_means.R b/R/get_means.R index c9f9f42..ed53fdf 100644 --- a/R/get_means.R +++ b/R/get_means.R @@ -144,9 +144,9 @@ get_means.lmerMod <- function(fit, formula=NULL, CI=95, ...){ names(means) <- stringr::str_replace(names(means), "emmean", "Mean") names(means) <- stringr::str_replace(names(means), "lower.CL", "CI_lower") - names(means) <- stringr::str_replace(names(means), "upper.CL", "CI_upper") + names(means) <- stringr::str_replace(names(means), "upper.CL", "CI_higher") names(means) <- stringr::str_replace(names(means), "asymp.LCL", "CI_lower") - names(means) <- stringr::str_replace(names(means), "asymp.UCL", "CI_upper") + names(means) <- stringr::str_replace(names(means), "asymp.UCL", "CI_higher") return(means) } From 7824b05624ebb1587e5bb6d206a21821f3f23fd8 Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Mon, 29 Oct 2018 13:57:16 +0100 Subject: [PATCH 10/17] Apply styler --- R/analyze.anova.R | 4 +- R/analyze.fa.R | 6 +- R/analyze.glm.R | 2 +- R/analyze.glmerMod.R | 2 +- R/analyze.htest.R | 6 +- R/analyze.lm.R | 4 +- R/analyze.lmerModLmerTest.R | 2 +- R/analyze.stanreg.R | 94 ++++++++++-------- R/assess.R | 20 ++-- R/bayes_cor.R | 6 +- R/correlation.R | 3 +- R/crawford.test.R | 26 ++--- R/crawford_dissociation.test.R | 2 +- R/create_intervals.R | 2 +- R/dprime.R | 2 +- R/find_best_model.lmerModLmerTest.R | 28 +++--- R/find_best_model.stanreg.R | 26 ++--- R/find_combinations.R | 2 +- R/find_season.R | 19 ++-- R/formatting.R | 2 +- R/get_R2.R | 4 +- R/get_contrasts.R | 38 ++++--- R/get_data.R | 3 +- R/get_means.R | 36 ++++--- R/get_predicted.glm.R | 2 +- R/get_predicted.lm.R | 2 +- R/get_predicted.merMod.R | 2 +- R/get_predicted.stanreg.R | 4 +- R/golden.R | 5 +- R/hdi.R | 3 +- R/interpret_R2.R | 6 +- R/interpret_RMSEA.R | 4 +- R/interpret_bf.R | 6 +- R/interpret_d.R | 6 +- R/interpret_odds.R | 8 +- R/interpret_omega_sq.R | 4 +- R/interpret_r.R | 6 +- R/is.standardized.R | 2 +- R/model_to_priors.R | 4 +- R/n_factors.R | 12 +-- R/odds_to_probs.R | 4 +- R/power_analysis.R | 2 +- R/probs_to_odds.R | 4 +- R/refdata.R | 10 +- R/rnorm_perfect.R | 2 +- R/rope.R | 2 +- R/simulate.R | 10 +- R/standardize.R | 15 ++- R/summary.psychobject.R | 2 +- .../2018-05-01-repeated_measure_anovas.md | 11 +- docs/~$index.html | Bin 162 -> 0 bytes tests/testthat/test-get_contrasts.R | 2 +- tests/testthat/test-get_means.R | 1 - tests/testthat/test-standardize.R | 7 +- 54 files changed, 242 insertions(+), 245 deletions(-) delete mode 100644 docs/~$index.html diff --git a/R/analyze.anova.R b/R/analyze.anova.R index 92bd7db..ab31f7f 100644 --- a/R/analyze.anova.R +++ b/R/analyze.anova.R @@ -48,7 +48,7 @@ #' @import broom #' #' @export -analyze.aov <- function(x, effsize_rules="field2013", ...) { +analyze.aov <- function(x, effsize_rules = "field2013", ...) { if (!"aov" %in% class(x)) { if (!"Residuals" %in% row.names(x)) { if (!is.null(x$Within)) { @@ -302,7 +302,7 @@ analyze.aovlist <- analyze.aov #' @author Arnoud Plantinga #' @importFrom stringr str_trim #' @export -omega_sq <- function(x, partial=TRUE) { +omega_sq <- function(x, partial = TRUE) { if ("aov" %in% class(x)) { summary_aov <- summary(x)[[1]] } else { diff --git a/R/analyze.fa.R b/R/analyze.fa.R index a4f23c3..fe2f11f 100644 --- a/R/analyze.fa.R +++ b/R/analyze.fa.R @@ -24,7 +24,7 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -analyze.fa <- function(x, labels=NULL, treshold="max", ...) { +analyze.fa <- function(x, labels = NULL, treshold = "max", ...) { loadings <- format_loadings(x, labels) values <- list() @@ -116,7 +116,7 @@ analyze.fa <- function(x, labels=NULL, treshold="max", ...) { #' #' @import dplyr #' @export -format_loadings <- function(x, labels=NULL) { +format_loadings <- function(x, labels = NULL) { # Check loadings and remove those inferior to a treshold @@ -204,7 +204,7 @@ get_loadings_max <- function(loadings) { #' #' @import dplyr #' @export -get_cfa_model <- function(loadings, treshold="max") { +get_cfa_model <- function(loadings, treshold = "max") { if (treshold == "max") { filtered_loadings <- get_loadings_max(loadings) } else { diff --git a/R/analyze.glm.R b/R/analyze.glm.R index ff7c139..ecccf8c 100644 --- a/R/analyze.glm.R +++ b/R/analyze.glm.R @@ -27,7 +27,7 @@ #' @importFrom stats formula #' @importFrom stringr str_squish #' @export -analyze.glm <- function(x, CI=95, effsize_rules="cohen1988", ...) { +analyze.glm <- function(x, CI = 95, effsize_rules = "cohen1988", ...) { # Processing diff --git a/R/analyze.glmerMod.R b/R/analyze.glmerMod.R index aec81e3..7bd311c 100644 --- a/R/analyze.glmerMod.R +++ b/R/analyze.glmerMod.R @@ -32,7 +32,7 @@ #' @import lmerTest #' @import dplyr #' @export -analyze.glmerMod <- function(x, CI=95, effsize_rules="cohen1988", ...) { +analyze.glmerMod <- function(x, CI = 95, effsize_rules = "cohen1988", ...) { # Processing diff --git a/R/analyze.htest.R b/R/analyze.htest.R index 0d4bc72..a424643 100644 --- a/R/analyze.htest.R +++ b/R/analyze.htest.R @@ -27,7 +27,7 @@ #' @import dplyr #' #' @export -analyze.htest <- function(x, effsize_rules="cohen1988", ...) { +analyze.htest <- function(x, effsize_rules = "cohen1988", ...) { # Processing @@ -71,7 +71,7 @@ analyze.htest <- function(x, effsize_rules="cohen1988", ...) { ")." ) - # T-TEST + # T-TEST } else if (grepl("t-test", values$method)) { if (names(x$null.value) == "mean") { means <- paste0( @@ -117,7 +117,7 @@ analyze.htest <- function(x, effsize_rules="cohen1988", ...) { format_p(values$p, stars = FALSE), ")." ) - # OTHER + # OTHER } else { stop(paste0("The ", values$method, " is not implemented yet.")) } diff --git a/R/analyze.lm.R b/R/analyze.lm.R index 466a65a..5f8166a 100644 --- a/R/analyze.lm.R +++ b/R/analyze.lm.R @@ -24,7 +24,7 @@ #' @importFrom stats formula #' @importFrom stringr str_squish #' @export -analyze.lm <- function(x, CI=95, effsize_rules="cohen1988", ...) { +analyze.lm <- function(x, CI = 95, effsize_rules = "cohen1988", ...) { # Processing @@ -50,7 +50,7 @@ analyze.lm <- function(x, CI=95, effsize_rules="cohen1988", ...) { summary$p <- summary$`Pr...t..` # standardized coefficients - standardized <- tibble::rownames_to_column(standardize(fit, method = "refit", data=data), "Variable") + standardized <- tibble::rownames_to_column(standardize(fit, method = "refit", data = data), "Variable") summary <- merge(summary, standardized, by = "Variable", all.x = TRUE, sort = FALSE) summary$Effect_Size <- c(NA, interpret_d(tail(summary$Coef_std, -1), rules = effsize_rules)) diff --git a/R/analyze.lmerModLmerTest.R b/R/analyze.lmerModLmerTest.R index 585ac5d..966d142 100644 --- a/R/analyze.lmerModLmerTest.R +++ b/R/analyze.lmerModLmerTest.R @@ -27,7 +27,7 @@ #' @importFrom stringr str_squish #' @import dplyr #' @export -analyze.lmerModLmerTest <- function(x, CI=95, effsize_rules="cohen1988", ...) { +analyze.lmerModLmerTest <- function(x, CI = 95, effsize_rules = "cohen1988", ...) { # Processing diff --git a/R/analyze.stanreg.R b/R/analyze.stanreg.R index 9d0d5cb..a24b7b0 100644 --- a/R/analyze.stanreg.R +++ b/R/analyze.stanreg.R @@ -66,7 +66,7 @@ #' @importFrom broom tidy #' @importFrom stringr str_squish str_replace #' @export -analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize=FALSE, effsize_rules="cohen1988", ...) { +analyze.stanreg <- function(x, CI = 90, index = "overlap", ROPE_bounds = NULL, effsize = FALSE, effsize_rules = "cohen1988", ...) { fit <- x # Info -------------------------------------------------------------------- @@ -169,8 +169,8 @@ analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize effsize = effsize, effsize_rules = effsize_rules, fit = fit, - index=index, - ROPE_bounds=ROPE_bounds + index = index, + ROPE_bounds = ROPE_bounds ) } } @@ -199,7 +199,7 @@ analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize if (effsize == FALSE) { summary <- select_(summary, "-Median_std", "-MAD_std") } - + if (index == "ROPE") { summary <- select_(summary, "-Overlap") } else { @@ -344,7 +344,7 @@ analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize #' @keywords internal -.get_info_priors <- function(varname, info_priors, predictors=NULL) { +.get_info_priors <- function(varname, info_priors, predictors = NULL) { # Prior # TBD: this doesn't work with categorical predictors :( values <- list() @@ -380,7 +380,7 @@ analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize #' @keywords internal -.process_R2 <- function(varname, posteriors, info_priors, R2.adj=NULL, CI=90, effsize=FALSE) { +.process_R2 <- function(varname, posteriors, info_priors, R2.adj = NULL, CI = 90, effsize = FALSE) { values <- .get_info_priors(varname, info_priors) posterior <- posteriors[, varname] @@ -458,7 +458,7 @@ analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize #' @keywords internal -.process_intercept <- function(varname, posteriors, info_priors, predictors, CI=90, effsize=FALSE) { +.process_intercept <- function(varname, posteriors, info_priors, predictors, CI = 90, effsize = FALSE) { values <- .get_info_priors(varname, info_priors, predictors) posterior <- posteriors[, varname] @@ -474,9 +474,9 @@ analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize values$MPE_values <- NA values$overlap <- NA values$ROPE <- NA - - - + + + # Text values$text <- paste0( " The intercept is at ", @@ -527,13 +527,12 @@ analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize posteriors_std, info_priors, predictors, - CI=90, - effsize=FALSE, - effsize_rules=FALSE, + CI = 90, + effsize = FALSE, + effsize_rules = FALSE, fit, - index="overlap", - ROPE_bounds=NULL) { - + index = "overlap", + ROPE_bounds = NULL) { values <- .get_info_priors(varname, info_priors, predictors) posterior <- posteriors[, varname] @@ -559,45 +558,54 @@ analyze.stanreg <- function(x, CI=90, index="overlap", ROPE_bounds=NULL, effsize ) ) - if(!is.null(ROPE_bounds)){ - rope <- rope(posterior, bounds=ROPE_bounds) + if (!is.null(ROPE_bounds)) { + rope <- rope(posterior, bounds = ROPE_bounds) values$ROPE_decision <- rope$rope_decision values$ROPE <- rope$rope_probability - }else{ + } else { values$ROPE <- NA values$ROPE_decision <- NA } - if(index == "overlap"){ - index <- paste0("Overlap = ", - format_digit(values$overlap, null_treshold = 0.01), - "%).") - } else if(index == "ROPE"){ - if(!is.null(ROPE_bounds)){ - index <- paste0("ROPE = ", - format_digit(values$ROPE, null_treshold = 0.001), - ").") - } else{ - if(effsize == TRUE){ - rope <- rope(posteriors_std[, varname], bounds=c(-0.1, 0.1)) + if (index == "overlap") { + index <- paste0( + "Overlap = ", + format_digit(values$overlap, null_treshold = 0.01), + "%)." + ) + } else if (index == "ROPE") { + if (!is.null(ROPE_bounds)) { + index <- paste0( + "ROPE = ", + format_digit(values$ROPE, null_treshold = 0.001), + ")." + ) + } else { + if (effsize == TRUE) { + rope <- rope(posteriors_std[, varname], bounds = c(-0.1, 0.1)) values$ROPE_decision <- rope$rope_decision values$ROPE <- rope$rope_probability - index <- paste0("ROPE = ", - format_digit(values$ROPE, null_treshold = 0.001), - ").") - } else{ + index <- paste0( + "ROPE = ", + format_digit(values$ROPE, null_treshold = 0.001), + ")." + ) + } else { warning("you need to specify ROPE_bounds (e.g. 'c(-0.1, 0.1)'). Computing overlap instead.") - index <- paste0("Overlap = ", - format_digit(values$overlap, null_treshold = 0.01), - "%).") + index <- paste0( + "Overlap = ", + format_digit(values$overlap, null_treshold = 0.01), + "%)." + ) } } - - } else{ + } else { warning("Parameter 'index' should be 'overlap' or 'ROPE'. Computing overlap.") - index <- paste0("Overlap = ", - format_digit(values$overlap, null_treshold = 0.01), - "%).") + index <- paste0( + "Overlap = ", + format_digit(values$overlap, null_treshold = 0.01), + "%)." + ) } diff --git a/R/assess.R b/R/assess.R index 3b3711d..aa5cadd 100644 --- a/R/assess.R +++ b/R/assess.R @@ -38,16 +38,16 @@ assess <- function(patient, sd = 1, n = NULL, controls = NULL, - CI=95, - treshold=0.05, - iter=10000, - color_controls="#2196F3", - color_CI="#E91E63", - color_score="black", - color_size=2, - alpha_controls=1, - alpha_CI=0.8, - verbose=TRUE) { + CI = 95, + treshold = 0.05, + iter = 10000, + color_controls = "#2196F3", + color_CI = "#E91E63", + color_score = "black", + color_size = 2, + alpha_controls = 1, + alpha_CI = 0.8, + verbose = TRUE) { if (is.null(controls)) { if (is.null(n)) { if (verbose == TRUE) { diff --git a/R/bayes_cor.R b/R/bayes_cor.R index e919cd6..d16b1e5 100644 --- a/R/bayes_cor.R +++ b/R/bayes_cor.R @@ -27,7 +27,7 @@ #' @importFrom stats complete.cases cor.test #' @import dplyr #' @export -bayes_cor.test <- function(x, y, CI=90, iterations = 10000, effsize_rules_r="cohen1988", effsize_rules_bf="jeffreys1961") { +bayes_cor.test <- function(x, y, CI = 90, iterations = 10000, effsize_rules_r = "cohen1988", effsize_rules_bf = "jeffreys1961") { # Varnames ---------------------------------------------------------------- @@ -169,7 +169,7 @@ bayes_cor.test <- function(x, y, CI=90, iterations = 10000, effsize_rules_r="coh #' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' @export -bayes_cor <- function(df, df2=NULL, reorder=TRUE) { +bayes_cor <- function(df, df2 = NULL, reorder = TRUE) { df <- purrr::keep(df, is.numeric) if (!is.null(df2)) { @@ -321,7 +321,7 @@ bayes_cor <- function(df, df2=NULL, reorder=TRUE) { #' #' @importFrom stats as.dist hclust #' @export -reorder_matrix <- function(mat, dmat=NULL) { +reorder_matrix <- function(mat, dmat = NULL) { if (is.null(dmat)) { dmat <- mat } diff --git a/R/correlation.R b/R/correlation.R index 20a0e51..546cd03 100644 --- a/R/correlation.R +++ b/R/correlation.R @@ -91,7 +91,6 @@ correlation <- function(df, t <- corr$t ci <- corr$ci ci.adj <- corr$ci.adj - } else { if (is.null(df2) == FALSE) { df <- cbind(df, df2) @@ -142,7 +141,7 @@ correlation <- function(df, if (is.null(p) == FALSE) { if (adjust != "none") { if ((type == "full" & is.null(df2) == FALSE) | (type == "semi")) { - p[,] <- p.adjust(p, method = adjust) + p[, ] <- p.adjust(p, method = adjust) } else { p[lower.tri(p)] <- p.adjust(p[lower.tri(p)], method = adjust, n = choose(nrow(p), 2)) p[upper.tri(p)] <- p.adjust(p[upper.tri(p)], method = adjust, n = choose(nrow(p), 2)) diff --git a/R/crawford.test.R b/R/crawford.test.R index 0d674c3..7e04a10 100644 --- a/R/crawford.test.R +++ b/R/crawford.test.R @@ -38,19 +38,19 @@ #' @import ggplot2 #' @export crawford.test <- function(patient, - controls=NULL, - mean=NULL, - sd=NULL, - n=NULL, - CI=95, - treshold=0.1, - iter=10000, - color_controls="#2196F3", - color_CI="#E91E63", - color_score="black", - color_size=2, - alpha_controls=1, - alpha_CI=0.8) { + controls = NULL, + mean = NULL, + sd = NULL, + n = NULL, + CI = 95, + treshold = 0.1, + iter = 10000, + color_controls = "#2196F3", + color_CI = "#E91E63", + color_score = "black", + color_size = 2, + alpha_controls = 1, + alpha_CI = 0.8) { if (is.null(controls)) { # Check if a parameter is null if (length(c(mean, sd, n)) != 3) { diff --git a/R/crawford_dissociation.test.R b/R/crawford_dissociation.test.R index 8fa2a66..bbee6f4 100644 --- a/R/crawford_dissociation.test.R +++ b/R/crawford_dissociation.test.R @@ -25,7 +25,7 @@ #' #' @importFrom stats sd pt #' @export -crawford_dissociation.test <- function(case_X, case_Y, controls_X, controls_Y, verbose=TRUE) { +crawford_dissociation.test <- function(case_X, case_Y, controls_X, controls_Y, verbose = TRUE) { X_mean <- mean(controls_X) X_sd <- sd(controls_X) Y_mean <- mean(controls_Y) diff --git a/R/create_intervals.R b/R/create_intervals.R index 0d2009a..4e04cd9 100644 --- a/R/create_intervals.R +++ b/R/create_intervals.R @@ -26,7 +26,7 @@ #' #' @importFrom ggplot2 cut_interval cut_number #' @export -create_intervals <- function(x, n=NULL, length=NULL, equal_range=TRUE, labels=NULL, dig.lab=3) { +create_intervals <- function(x, n = NULL, length = NULL, equal_range = TRUE, labels = NULL, dig.lab = 3) { if (equal_range) { if (is.character(labels) && labels == "median") { cuts <- ggplot2::cut_interval(x, n = n, length = length, labels = FALSE) diff --git a/R/dprime.R b/R/dprime.R index 70b41f9..6e58ac2 100644 --- a/R/dprime.R +++ b/R/dprime.R @@ -51,7 +51,7 @@ #' #' @importFrom stats qnorm #' @export -dprime <- function(n_hit, n_fa, n_miss=NULL, n_cr=NULL, n_targets=NULL, n_distractors=NULL, adjusted=TRUE) { +dprime <- function(n_hit, n_fa, n_miss = NULL, n_cr = NULL, n_targets = NULL, n_distractors = NULL, adjusted = TRUE) { if (is.null(n_targets)) { n_targets <- n_hit + n_miss } diff --git a/R/find_best_model.lmerModLmerTest.R b/R/find_best_model.lmerModLmerTest.R index 28e0743..3a6a12d 100644 --- a/R/find_best_model.lmerModLmerTest.R +++ b/R/find_best_model.lmerModLmerTest.R @@ -31,16 +31,16 @@ #' #' @method find_best_model lmerModLmerTest #' @export -find_best_model.lmerModLmerTest <- function(fit, interaction=TRUE, fixed=NULL, ...) { +find_best_model.lmerModLmerTest <- function(fit, interaction = TRUE, fixed = NULL, ...) { # Extract infos combinations <- find_combinations(as.formula(get_formula(fit)), interaction = interaction, fixed = fixed) - + # Recreating the dataset without NA dataComplete <- fit@frame[complete.cases(fit@frame), ] - - + + # fit models models <- c() for (formula in combinations) { @@ -51,25 +51,25 @@ find_best_model.lmerModLmerTest <- function(fit, interaction=TRUE, fixed=NULL, . # No warning messages for this part options(warn = -1) - + # Model comparison comparison <- as.data.frame(do.call("anova", models)) - + # Re-displaying warning messages options(warn = 0) - + # Creating row names to the combinations array equivalent to the comparison data frame - combinations <- as.data.frame(combinations,row.names = paste0("MODEL", seq(1,length(combinations)))) + combinations <- as.data.frame(combinations, row.names = paste0("MODEL", seq(1, length(combinations)))) # Reordering the rows in the same way for both combinations and comparison before implementing the formulas - comparison <- comparison[ order(row.names(comparison)),] - comparison$formula <- combinations[order(row.names(combinations)),] - + comparison <- comparison[ order(row.names(comparison)), ] + comparison$formula <- combinations[order(row.names(combinations)), ] + # Sorting the data frame by the AIC then BIC - comparison <- comparison[order(comparison$AIC,comparison$BIC),] - + comparison <- comparison[order(comparison$AIC, comparison$BIC), ] + + - # Best model by criterion best_aic <- dplyr::arrange_(comparison, "AIC") %>% dplyr::select_("formula") %>% diff --git a/R/find_best_model.stanreg.R b/R/find_best_model.stanreg.R index 54b155b..ac58b70 100644 --- a/R/find_best_model.stanreg.R +++ b/R/find_best_model.stanreg.R @@ -42,7 +42,7 @@ #' #' @method find_best_model stanreg #' @export -find_best_model.stanreg <- function(fit, interaction=TRUE, fixed=NULL, K=10, k_treshold=NULL, ...) { +find_best_model.stanreg <- function(fit, interaction = TRUE, fixed = NULL, K = 10, k_treshold = NULL, ...) { # Extract infos combinations <- find_combinations(fit$formula, interaction = interaction, fixed = fixed) @@ -58,15 +58,15 @@ find_best_model.stanreg <- function(fit, interaction=TRUE, fixed=NULL, K=10, k_t formula <- combinations[i] newfit <- update(fit, formula = formula, verbose = FALSE) R2s[[formula]] <- median(rstanarm::bayes_R2(newfit)) - - + + if (!is.null(k_treshold)) { loo <- rstanarm::loo(newfit, k_treshold = k_treshold) } else { loo <- rstanarm::loo(newfit) } - - + + complexities[[formula]] <- length(newfit$coefficients) loos[[formula]] <- loo if (K > 1) { @@ -88,14 +88,14 @@ find_best_model.stanreg <- function(fit, interaction=TRUE, fixed=NULL, K=10, k_t formula = formula, complexity = complexity - 1, R2 = R2s[[formula]], - looic = Estimates["looic","Estimate"], - looic_se = Estimates["looic","SE"], - elpd_loo = Estimates["elpd_loo","Estimate"], - elpd_loo_se = Estimates["elpd_loo","SE"], - p_loo = Estimates["p_loo","Estimate"], - p_loo_se = Estimates["p_loo","SE"], - elpd_kfold = Estimates["p_loo","Estimate"], - elpd_kfold_se = Estimates["p_loo","SE"] + looic = Estimates["looic", "Estimate"], + looic_se = Estimates["looic", "SE"], + elpd_loo = Estimates["elpd_loo", "Estimate"], + elpd_loo_se = Estimates["elpd_loo", "SE"], + p_loo = Estimates["p_loo", "Estimate"], + p_loo_se = Estimates["p_loo", "SE"], + elpd_kfold = Estimates["p_loo", "Estimate"], + elpd_kfold_se = Estimates["p_loo", "SE"] ) comparison <- rbind(comparison, model) } diff --git a/R/find_combinations.R b/R/find_combinations.R index 40fc343..5ed79a8 100644 --- a/R/find_combinations.R +++ b/R/find_combinations.R @@ -52,7 +52,7 @@ find_combinations <- function(object, ...) { #' @importFrom utils combn #' @importFrom stats terms #' @export -find_combinations.formula <- function(object, interaction=TRUE, fixed=NULL, ...) { +find_combinations.formula <- function(object, interaction = TRUE, fixed = NULL, ...) { # Extract infos formula <- object diff --git a/R/find_season.R b/R/find_season.R index 2120631..a9beedb 100644 --- a/R/find_season.R +++ b/R/find_season.R @@ -22,18 +22,19 @@ #' https://stackoverflow.com/questions/9500114/find-which-season-a-particular-date-belongs-to #' #' @export -find_season <- function(dates, winter="12-21", spring="3-20", summer="6-21", fall="9-22") { - +find_season <- function(dates, winter = "12-21", spring = "3-20", summer = "6-21", fall = "9-22") { WS <- as.Date(paste0("2012-", winter), format = "%Y-%m-%d") # Winter Solstice - SE <- as.Date(paste0("2012-", spring), format = "%Y-%m-%d") # Spring Equinox - SS <- as.Date(paste0("2012-", summer), format = "%Y-%m-%d") # Summer Solstice - FE <- as.Date(paste0("2012-", fall), format = "%Y-%m-%d") # Fall Equinox + SE <- as.Date(paste0("2012-", spring), format = "%Y-%m-%d") # Spring Equinox + SS <- as.Date(paste0("2012-", summer), format = "%Y-%m-%d") # Summer Solstice + FE <- as.Date(paste0("2012-", fall), format = "%Y-%m-%d") # Fall Equinox # Convert dates from any year to 2012 dates - d <- as.Date(strftime(as.character(dates), format="2012-%m-%d")) + d <- as.Date(strftime(as.character(dates), format = "2012-%m-%d")) - season <- ifelse (d >= WS | d < SE, "Winter", - ifelse (d >= SE & d < SS, "Spring", - ifelse (d >= SS & d < FE, "Summer", "Fall"))) + season <- ifelse(d >= WS | d < SE, "Winter", + ifelse(d >= SE & d < SS, "Spring", + ifelse(d >= SS & d < FE, "Summer", "Fall") + ) + ) return(season) } diff --git a/R/formatting.R b/R/formatting.R index a33d88d..f74d651 100644 --- a/R/formatting.R +++ b/R/formatting.R @@ -84,7 +84,7 @@ format_string <- function(x, fmt, ...) { #' #' @importFrom stringr str_remove_all #' @export -format_p <- function(pvalues, stars=TRUE) { +format_p <- function(pvalues, stars = TRUE) { p <- ifelse(pvalues < 0.001, "< .001***", ifelse(pvalues < 0.01, "< .01**", ifelse(pvalues < 0.05, "< .05*", diff --git a/R/get_R2.R b/R/get_R2.R index 023f4ba..405aaf7 100644 --- a/R/get_R2.R +++ b/R/get_R2.R @@ -69,7 +69,7 @@ get_R2.lm <- function(fit, ...) { #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -get_R2.glm <- function(fit, method="nakagawa", ...) { +get_R2.glm <- function(fit, method = "nakagawa", ...) { if (method == "nakagawa") { R2 <- as.numeric(R2_nakagawa(fit)$R2m) } else if (method == "tjur") { @@ -107,7 +107,7 @@ get_R2.glm <- function(fit, method="nakagawa", ...) { #' @seealso \link[=bayes_R2.stanreg]{"bayes_R2.stanreg"} #' #' @export -get_R2.stanreg <- function(fit, silent=FALSE, ...) { +get_R2.stanreg <- function(fit, silent = FALSE, ...) { tryCatch({ R2 <- rstanarm::bayes_R2(fit) }, error = function(e) { diff --git a/R/get_contrasts.R b/R/get_contrasts.R index 9ea4829..49145a4 100644 --- a/R/get_contrasts.R +++ b/R/get_contrasts.R @@ -57,7 +57,7 @@ get_contrasts <- function(fit, ...) { #' @param ... Arguments passed to or from other methods. #' @method get_contrasts stanreg #' @export -get_contrasts.stanreg <- function(fit, formula=NULL, CI=90, ROPE_bounds=NULL, overlap=FALSE, ...){ +get_contrasts.stanreg <- function(fit, formula = NULL, CI = 90, ROPE_bounds = NULL, overlap = FALSE, ...) { .get_contrasts_bayes(fit, formula, CI, ROPE_bounds, overlap, ...) } @@ -75,7 +75,7 @@ get_contrasts.stanreg <- function(fit, formula=NULL, CI=90, ROPE_bounds=NULL, ov #' @param ... Arguments passed to or from other methods. #' @method get_contrasts lm #' @export -get_contrasts.lm <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ +get_contrasts.lm <- function(fit, formula = NULL, CI = 95, adjust = "tukey", ...) { .get_contrasts_freq(fit, formula, CI, adjust, ...) } @@ -86,7 +86,7 @@ get_contrasts.lm <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ #' @inheritParams get_contrasts.lm #' @method get_contrasts glm #' @export -get_contrasts.glm <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ +get_contrasts.glm <- function(fit, formula = NULL, CI = 95, adjust = "tukey", ...) { .get_contrasts_freq(fit, formula, CI, adjust, ...) } @@ -97,7 +97,7 @@ get_contrasts.glm <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ #' @inheritParams get_contrasts.lm #' @method get_contrasts lmerModLmerTest #' @export -get_contrasts.lmerModLmerTest <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ +get_contrasts.lmerModLmerTest <- function(fit, formula = NULL, CI = 95, adjust = "tukey", ...) { .get_contrasts_freq(fit, formula, CI, adjust, ...) } @@ -108,7 +108,7 @@ get_contrasts.lmerModLmerTest <- function(fit, formula=NULL, CI=95, adjust="tuke #' @inheritParams get_contrasts.lm #' @method get_contrasts glmerMod #' @export -get_contrasts.glmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ +get_contrasts.glmerMod <- function(fit, formula = NULL, CI = 95, adjust = "tukey", ...) { .get_contrasts_freq(fit, formula, CI, adjust, ...) } @@ -119,7 +119,7 @@ get_contrasts.glmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ... #' @inheritParams get_contrasts.lm #' @method get_contrasts lmerMod #' @export -get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...){ +get_contrasts.lmerMod <- function(fit, formula = NULL, CI = 95, adjust = "tukey", ...) { .get_contrasts_freq(fit, formula, CI, adjust, ...) } @@ -131,13 +131,12 @@ get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) #' @importFrom graphics pairs #' @importFrom stats confint mad #' @keywords internal -.get_contrasts_bayes <- function(fit, formula=NULL, CI=90, ROPE_bounds=NULL, overlap=FALSE, ...) { - - if(is.null(formula)){ - formula <- paste(get_info(fit)$predictors, collapse=" * ") +.get_contrasts_bayes <- function(fit, formula = NULL, CI = 90, ROPE_bounds = NULL, overlap = FALSE, ...) { + if (is.null(formula)) { + formula <- paste(get_info(fit)$predictors, collapse = " * ") } - if(is.character(formula)){ + if (is.character(formula)) { formula <- as.formula(paste0("~ ", formula)) } @@ -155,7 +154,7 @@ get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) for (name in names(contrasts_posterior)) { posterior <- contrasts_posterior[[name]] - CI_values <- HDI(posterior, prob = CI/100) + CI_values <- HDI(posterior, prob = CI / 100) CI_values <- c(CI_values$values$HDImin, CI_values$values$HDImax) var <- data.frame( @@ -167,7 +166,7 @@ get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) MPE = mpe(posterior)$MPE ) - if(overlap == TRUE){ + if (overlap == TRUE) { var$Overlap <- 100 * overlap( posterior, rnorm_perfect( @@ -178,7 +177,7 @@ get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) ) } - if(!is.null(ROPE_bounds)){ + if (!is.null(ROPE_bounds)) { var$ROPE <- rope(posterior, ROPE_bounds, CI = 95)$rope_probability } @@ -197,13 +196,12 @@ get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) #' @importFrom graphics pairs #' @importFrom stats confint #' @keywords internal -.get_contrasts_freq <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) { - - if(is.null(formula)){ - formula <- paste(get_info(fit)$predictors, collapse=" * ") +.get_contrasts_freq <- function(fit, formula = NULL, CI = 95, adjust = "tukey", ...) { + if (is.null(formula)) { + formula <- paste(get_info(fit)$predictors, collapse = " * ") } - if(is.character(formula)){ + if (is.character(formula)) { formula <- as.formula(paste0("~ ", formula)) } @@ -214,7 +212,7 @@ get_contrasts.lmerMod <- function(fit, formula=NULL, CI=95, adjust="tukey", ...) # Confint CI <- contrasts %>% - confint(CI/100) %>% + confint(CI / 100) %>% select(contains("CL")) diff --git a/R/get_data.R b/R/get_data.R index e67dbc8..0a9e951 100644 --- a/R/get_data.R +++ b/R/get_data.R @@ -28,7 +28,7 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' @export get_data <- function(fit, ...) { -UseMethod("get_data") + UseMethod("get_data") } @@ -36,7 +36,6 @@ UseMethod("get_data") #' @importFrom utils data #' @export get_data.lm <- function(fit, ...) { - tryCatch({ data <- eval(getCall(fit)$data, environment(formula(fit))) return(data) diff --git a/R/get_means.R b/R/get_means.R index ed53fdf..798da42 100644 --- a/R/get_means.R +++ b/R/get_means.R @@ -32,44 +32,44 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -get_means <- function(fit, formula=NULL, CI=90, ...) { +get_means <- function(fit, formula = NULL, CI = 90, ...) { UseMethod("get_means") } #' @method get_means stanreg #' @export -get_means.stanreg <- function(fit, formula=NULL, CI=90, ...){ +get_means.stanreg <- function(fit, formula = NULL, CI = 90, ...) { .get_means_bayes(fit, formula, CI, ...) } #' @method get_means lm #' @export -get_means.lm <- function(fit, formula=NULL, CI=95, ...){ +get_means.lm <- function(fit, formula = NULL, CI = 95, ...) { .get_means_freq(fit, formula, CI, ...) } #' @method get_means glm #' @export -get_means.glm <- function(fit, formula=NULL, CI=95, ...){ +get_means.glm <- function(fit, formula = NULL, CI = 95, ...) { .get_means_freq(fit, formula, CI, ...) } #' @method get_means lmerModLmerTest #' @export -get_means.lmerModLmerTest <- function(fit, formula=NULL, CI=95, ...){ +get_means.lmerModLmerTest <- function(fit, formula = NULL, CI = 95, ...) { .get_means_freq(fit, formula, CI, ...) } #' @method get_means glmerMod #' @export -get_means.glmerMod <- function(fit, formula=NULL, CI=95, ...){ +get_means.glmerMod <- function(fit, formula = NULL, CI = 95, ...) { .get_means_freq(fit, formula, CI, ...) } #' @method get_means lmerMod #' @export -get_means.lmerMod <- function(fit, formula=NULL, CI=95, ...){ +get_means.lmerMod <- function(fit, formula = NULL, CI = 95, ...) { .get_means_freq(fit, formula, CI, ...) } @@ -80,13 +80,12 @@ get_means.lmerMod <- function(fit, formula=NULL, CI=95, ...){ #' @importFrom emmeans emmeans #' @importFrom stats confint mad #' @keywords internal -.get_means_bayes <- function(fit, formula=NULL, CI=90, ...) { - - if(is.null(formula)){ - formula <- paste(get_info(fit)$predictors, collapse=" * ") +.get_means_bayes <- function(fit, formula = NULL, CI = 90, ...) { + if (is.null(formula)) { + formula <- paste(get_info(fit)$predictors, collapse = " * ") } - if(is.character(formula)){ + if (is.character(formula)) { formula <- as.formula(paste0("~ ", formula)) } @@ -102,7 +101,7 @@ get_means.lmerMod <- function(fit, formula=NULL, CI=95, ...){ for (name in names(means_posterior)) { var <- means_posterior[[name]] - CI_values <- HDI(var, prob = CI/100) + CI_values <- HDI(var, prob = CI / 100) CI_values <- c(CI_values$values$HDImin, CI_values$values$HDImax) var <- data.frame( @@ -126,20 +125,19 @@ get_means.lmerMod <- function(fit, formula=NULL, CI=95, ...){ #' @importFrom emmeans emmeans #' @importFrom stats confint #' @keywords internal -.get_means_freq <- function(fit, formula=NULL, CI=95, ...) { - - if(is.null(formula)){ - formula <- paste(get_info(fit)$predictors, collapse=" * ") +.get_means_freq <- function(fit, formula = NULL, CI = 95, ...) { + if (is.null(formula)) { + formula <- paste(get_info(fit)$predictors, collapse = " * ") } - if(is.character(formula)){ + if (is.character(formula)) { formula <- as.formula(paste0("~ ", formula)) } # Means --------------------------------------------------------------- means <- fit %>% emmeans::emmeans(formula, ...) %>% - confint(CI/100) %>% + confint(CI / 100) %>% as.data.frame() names(means) <- stringr::str_replace(names(means), "emmean", "Mean") diff --git a/R/get_predicted.glm.R b/R/get_predicted.glm.R index 4242118..8ee73b7 100644 --- a/R/get_predicted.glm.R +++ b/R/get_predicted.glm.R @@ -34,7 +34,7 @@ #' @importFrom dplyr bind_cols #' @importFrom tibble rownames_to_column #' @export -get_predicted.glm <- function(fit, newdata="model", prob=0.95, odds_to_probs=TRUE, ...) { +get_predicted.glm <- function(fit, newdata = "model", prob = 0.95, odds_to_probs = TRUE, ...) { # Extract names diff --git a/R/get_predicted.lm.R b/R/get_predicted.lm.R index db74cad..f99fd1f 100644 --- a/R/get_predicted.lm.R +++ b/R/get_predicted.lm.R @@ -34,7 +34,7 @@ #' @importFrom dplyr bind_cols #' @importFrom tibble rownames_to_column #' @export -get_predicted.lm <- function(fit, newdata="model", prob=0.95, ...) { +get_predicted.lm <- function(fit, newdata = "model", prob = 0.95, ...) { # Extract names diff --git a/R/get_predicted.merMod.R b/R/get_predicted.merMod.R index 365add8..c7ff39a 100644 --- a/R/get_predicted.merMod.R +++ b/R/get_predicted.merMod.R @@ -99,7 +99,7 @@ get_predicted.merMod <- function(fit, newdata="model", prob=NULL, odds_to_probs= if (!is.null(prob)) { predFun <- function(fit) { - predict(fit, newdata) + predict(fit, newdata, newdata = newdata, re.form = re.form) } predMat <- lme4::bootMer(fit, nsim = iter, FUN = predFun, use.u = use.u, seed = seed)$t diff --git a/R/get_predicted.stanreg.R b/R/get_predicted.stanreg.R index 04c7244..393227f 100644 --- a/R/get_predicted.stanreg.R +++ b/R/get_predicted.stanreg.R @@ -53,7 +53,7 @@ #' @importFrom dplyr bind_cols #' @importFrom tibble rownames_to_column #' @export -get_predicted.stanreg <- function(fit, newdata="model", prob=0.9, odds_to_probs=TRUE, keep_iterations=FALSE, draws=NULL, posterior_predict=FALSE, seed=NULL, transform=FALSE, ...) { +get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_probs = TRUE, keep_iterations = FALSE, draws = NULL, posterior_predict = FALSE, seed = NULL, transform = FALSE, ...) { # Extract names predictors <- all.vars(as.formula(fit$formula)) @@ -88,7 +88,7 @@ get_predicted.stanreg <- function(fit, newdata="model", prob=0.9, odds_to_probs= # Generate draws ------------------------------------------------------- if (posterior_predict == FALSE) { - posterior <- rstanarm::posterior_linpred(fit, newdata = newdata, re.form = re.form, seed = seed, draws = draws, transform=transform) + posterior <- rstanarm::posterior_linpred(fit, newdata = newdata, re.form = re.form, seed = seed, draws = draws, transform = transform) } else { posterior <- rstanarm::posterior_predict(fit, newdata = newdata, re.form = re.form, seed = seed, draws = draws) } diff --git a/R/golden.R b/R/golden.R index 05d67e2..98e6eed 100644 --- a/R/golden.R +++ b/R/golden.R @@ -13,7 +13,6 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -golden <- function(x=1) { - return(x*(1+sqrt(5))/2) +golden <- function(x = 1) { + return(x * (1 + sqrt(5)) / 2) } - diff --git a/R/hdi.R b/R/hdi.R index a90cc1a..ab34344 100644 --- a/R/hdi.R +++ b/R/hdi.R @@ -126,9 +126,8 @@ HDImax <- function(x, prob = .95) { x <- sort(x) ci.index <- ceiling(prob * length(x)) nCIs <- length(x) - ci.index - ci.width <- purrr::map_dbl(1:nCIs, ~ x[.x + ci.index] - x[.x]) + ci.width <- purrr::map_dbl(1:nCIs, ~x[.x + ci.index] - x[.x]) HDImin <- x[which.min(ci.width)] HDImax <- x[which.min(ci.width) + ci.index] return(c(HDImin, HDImax)) } - diff --git a/R/interpret_R2.R b/R/interpret_R2.R index 4c0572c..95f3881 100644 --- a/R/interpret_R2.R +++ b/R/interpret_R2.R @@ -13,7 +13,7 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -interpret_R2 <- function(x, rules="cohen1988") { +interpret_R2 <- function(x, rules = "cohen1988") { interpretation <- sapply(x, .interpret_R2, rules = rules, return_rules = FALSE) return(interpretation) } @@ -37,7 +37,7 @@ interpret_R2 <- function(x, rules="cohen1988") { #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -interpret_R2_posterior <- function(posterior, rules="cohen1988") { +interpret_R2_posterior <- function(posterior, rules = "cohen1988") { interpretation <- sapply(posterior, .interpret_R2, rules = rules) rules <- unlist(interpretation[, 1]$rules) interpretation <- as.data.frame(unlist(interpretation[1, ])) @@ -101,7 +101,7 @@ interpret_R2_posterior <- function(posterior, rules="cohen1988") { #' @keywords internal -.interpret_R2 <- function(x, rules="cohen1988", return_rules=TRUE) { +.interpret_R2 <- function(x, rules = "cohen1988", return_rules = TRUE) { if (!is.list(rules)) { if (rules == "cohen1988") { rules <- list( diff --git a/R/interpret_RMSEA.R b/R/interpret_RMSEA.R index cb7ab0f..58653d4 100644 --- a/R/interpret_RMSEA.R +++ b/R/interpret_RMSEA.R @@ -12,7 +12,7 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -interpret_RMSEA <- function(x, rules="awang2012") { +interpret_RMSEA <- function(x, rules = "awang2012") { interpretation <- sapply(x, .interpret_RMSEA, rules = rules, return_rules = FALSE) return(interpretation) } @@ -22,7 +22,7 @@ interpret_RMSEA <- function(x, rules="awang2012") { #' @keywords internal -.interpret_RMSEA <- function(x, rules="awang2012", return_rules=TRUE) { +.interpret_RMSEA <- function(x, rules = "awang2012", return_rules = TRUE) { if (!is.list(rules)) { if (rules == "awang2012") { rules <- list( diff --git a/R/interpret_bf.R b/R/interpret_bf.R index c32dc9b..23dae0b 100644 --- a/R/interpret_bf.R +++ b/R/interpret_bf.R @@ -20,7 +20,7 @@ #' \item{Jarosz, A. F., & Wiley, J. (2014). What are the odds? A practical guide to computing and reporting Bayes factors. The Journal of Problem Solving, 7(1), 2.} #' } #' @export -interpret_bf <- function(x, direction=TRUE, bf=TRUE, rules="jeffreys1961") { +interpret_bf <- function(x, direction = TRUE, bf = TRUE, rules = "jeffreys1961") { interpretation <- sapply(x, .interpret_bf, direction = direction, bf = bf, rules = rules, return_rules = FALSE) return(interpretation) } @@ -37,7 +37,7 @@ interpret_bf <- function(x, direction=TRUE, bf=TRUE, rules="jeffreys1961") { #' @param max Treshold for maximum. #' #' @export -format_bf <- function(bf, max=100) { +format_bf <- function(bf, max = 100) { if (bf > max) { bf <- paste0("BF > ", max) } else { @@ -56,7 +56,7 @@ format_bf <- function(bf, max=100) { #' @keywords internal -.interpret_bf <- function(x, direction=TRUE, bf=TRUE, rules="jeffreys1961", return_rules=TRUE) { +.interpret_bf <- function(x, direction = TRUE, bf = TRUE, rules = "jeffreys1961", return_rules = TRUE) { if (x < 1) { x <- 1 / abs(x) dir <- "against" diff --git a/R/interpret_d.R b/R/interpret_d.R index 3b57473..147a6c0 100644 --- a/R/interpret_d.R +++ b/R/interpret_d.R @@ -14,7 +14,7 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -interpret_d <- function(x, direction=FALSE, rules="cohen1988") { +interpret_d <- function(x, direction = FALSE, rules = "cohen1988") { interpretation <- sapply(x, .interpret_d, direction = direction, rules = rules, return_rules = FALSE) return(interpretation) } @@ -41,7 +41,7 @@ interpret_d <- function(x, direction=FALSE, rules="cohen1988") { #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -interpret_d_posterior <- function(posterior, rules="cohen1988") { +interpret_d_posterior <- function(posterior, rules = "cohen1988") { interpretation <- sapply(posterior, .interpret_d, rules = rules, direction = TRUE, return_rules = TRUE) rules <- unlist(interpretation[, 1]$rules) interpretation <- as.data.frame(unlist(interpretation[1, ])) @@ -123,7 +123,7 @@ interpret_d_posterior <- function(posterior, rules="cohen1988") { #' @keywords internal -.interpret_d <- function(x, direction=FALSE, rules="cohen1988", return_rules=TRUE) { +.interpret_d <- function(x, direction = FALSE, rules = "cohen1988", return_rules = TRUE) { if (!is.list(rules)) { if (rules == "cohen1988") { rules <- list( diff --git a/R/interpret_odds.R b/R/interpret_odds.R index fc2d0c9..b5a90c7 100644 --- a/R/interpret_odds.R +++ b/R/interpret_odds.R @@ -20,7 +20,7 @@ #' \item{Chen, H., Cohen, P., & Chen, S. (2010). How big is a big odds ratio? Interpreting the magnitudes of odds ratios in epidemiological studies. Communications in Statistics—Simulation and Computation®, 39(4), 860-864.} #' } #' @export -interpret_odds <- function(x, log=FALSE, direction=FALSE, rules="chen2010") { +interpret_odds <- function(x, log = FALSE, direction = FALSE, rules = "chen2010") { if (rules %in% c("cohen1988", "sawilowsky2009")) { interpretation <- sapply(odds_to_d(x, log = log), .interpret_d, direction = direction, rules = rules, return_rules = FALSE) } else { @@ -56,7 +56,7 @@ interpret_odds <- function(x, log=FALSE, direction=FALSE, rules="chen2010") { #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -interpret_odds_posterior <- function(posterior, log=FALSE, rules="chen2010") { +interpret_odds_posterior <- function(posterior, log = FALSE, rules = "chen2010") { if (rules %in% c("cohen1988", "sawilowsky2009")) { posterior <- odds_to_d(posterior, log = log) interpretation <- sapply(posterior, .interpret_d, direction = TRUE, rules = rules, return_rules = TRUE) @@ -145,7 +145,7 @@ interpret_odds_posterior <- function(posterior, log=FALSE, rules="chen2010") { #' @keywords internal -.interpret_odds <- function(x, log=FALSE, direction=FALSE, rules="chen2010", return_rules=TRUE) { +.interpret_odds <- function(x, log = FALSE, direction = FALSE, rules = "chen2010", return_rules = TRUE) { if (x > 0) { d <- "positive" } else { @@ -225,7 +225,7 @@ interpret_odds_posterior <- function(posterior, log=FALSE, rules="chen2010") { #' \item{Sánchez-Meca, J., Marín-Martínez, F., & Chacón-Moscoso, S. (2003). Effect-size indices for dichotomized outcomes in meta-analysis. Psychological methods, 8(4), 448.} #' } #' @export -odds_to_d <- function(x, log=TRUE) { +odds_to_d <- function(x, log = TRUE) { if (log == FALSE) { x <- log(x) } diff --git a/R/interpret_omega_sq.R b/R/interpret_omega_sq.R index e1b0f1b..69e907f 100644 --- a/R/interpret_omega_sq.R +++ b/R/interpret_omega_sq.R @@ -18,7 +18,7 @@ #' \item{Field, A (2013) Discovering statistics using IBM SPSS Statistics. Fourth Edition. Sage:London.} #' } #' @export -interpret_omega_sq <- function(x, rules="field2013") { +interpret_omega_sq <- function(x, rules = "field2013") { interpretation <- sapply(x, .interpret_omega_sq, rules = rules, return_rules = FALSE) return(interpretation) } @@ -29,7 +29,7 @@ interpret_omega_sq <- function(x, rules="field2013") { #' @keywords internal -.interpret_omega_sq <- function(x, rules="field2013", return_rules=TRUE) { +.interpret_omega_sq <- function(x, rules = "field2013", return_rules = TRUE) { if (!is.list(rules)) { if (rules == "field2013") { rules <- list( diff --git a/R/interpret_r.R b/R/interpret_r.R index da37529..8cae11b 100644 --- a/R/interpret_r.R +++ b/R/interpret_r.R @@ -17,7 +17,7 @@ #' @seealso Page 88 of APA's 6th Edition #' #' @export -interpret_r <- function(x, direction=TRUE, strength=TRUE, rules="cohen1988") { +interpret_r <- function(x, direction = TRUE, strength = TRUE, rules = "cohen1988") { interpretation <- sapply(x, .interpret_r, direction = direction, strength = strength, rules = rules, return_rules = FALSE) return(interpretation) } @@ -47,7 +47,7 @@ interpret_r <- function(x, direction=TRUE, strength=TRUE, rules="cohen1988") { #' @seealso Page 88 of APA's 6th Edition #' #' @export -interpret_r_posterior <- function(posterior, rules="cohen1988") { +interpret_r_posterior <- function(posterior, rules = "cohen1988") { interpretation <- sapply(posterior, .interpret_r, rules = rules) rules <- unlist(interpretation[, 1]$rules) interpretation <- as.data.frame(unlist(interpretation[1, ])) @@ -133,7 +133,7 @@ interpret_r_posterior <- function(posterior, rules="cohen1988") { #' @keywords internal -.interpret_r <- function(x, direction=TRUE, strength=TRUE, rules="cohen1988", return_rules=TRUE) { +.interpret_r <- function(x, direction = TRUE, strength = TRUE, rules = "cohen1988", return_rules = TRUE) { if (!is.list(rules)) { if (rules == "evans1996") { rules <- list( diff --git a/R/is.standardized.R b/R/is.standardized.R index f446637..aad5cdc 100644 --- a/R/is.standardized.R +++ b/R/is.standardized.R @@ -20,7 +20,7 @@ #' #' @import purrr #' @export -is.standardized <- function(df, tol=0.1) { +is.standardized <- function(df, tol = 0.1) { dfZ <- standardize(df) dfZnum <- purrr::keep(dfZ, is.numeric) diff --git a/R/model_to_priors.R b/R/model_to_priors.R index faa796c..3189f8c 100644 --- a/R/model_to_priors.R +++ b/R/model_to_priors.R @@ -31,7 +31,7 @@ #' @importFrom stats update #' @importFrom rstanarm normal #' @export -model_to_priors <- function(fit, autoscale=FALSE) { +model_to_priors <- function(fit, autoscale = FALSE) { posteriors <- as.data.frame(fit) # Varnames @@ -75,7 +75,7 @@ model_to_priors <- function(fit, autoscale=FALSE) { #' @keywords internal -.format_priors <- function(priors, autoscale=FALSE) { +.format_priors <- function(priors, autoscale = FALSE) { prior_mean <- data.frame(priors) %>% select(contains("mean")) %>% gather() %>% diff --git a/R/n_factors.R b/R/n_factors.R index 74f16b3..7cc8c99 100644 --- a/R/n_factors.R +++ b/R/n_factors.R @@ -33,7 +33,7 @@ #' @importFrom stats dnorm #' @importFrom stats qnorm #' @export -n_factors <- function(df, rotate="varimax", fm="minres", n=NULL) { +n_factors <- function(df, rotate = "varimax", fm = "minres", n = NULL) { # Copy the parallel function from nFactors to correct the use of mvrnorm parallel <- function(subject = 100, var = 10, rep = 100, cent = 0.05, @@ -101,7 +101,7 @@ n_factors <- function(df, rotate="varimax", fm="minres", n=NULL) { "Exp.Variance" = "Prop", "Cum.Variance" = "Cumu" ) %>% - mutate_("n.Factors" = ~ seq_len(nrow(nS$Analysis))) + mutate_("n.Factors" = ~seq_len(nrow(nS$Analysis))) @@ -190,15 +190,15 @@ n_factors <- function(df, rotate="varimax", fm="minres", n=NULL) { eigenvalues <- results %>% group_by_("n_optimal") %>% - summarise_("n_method" = ~ n()) %>% - mutate_("n_optimal" = ~ factor(n_optimal, levels = seq_len(nrow(eigenvalues)))) %>% + summarise_("n_method" = ~n()) %>% + mutate_("n_optimal" = ~factor(n_optimal, levels = seq_len(nrow(eigenvalues)))) %>% complete_("n_optimal", fill = list(n_method = 0)) %>% arrange_("n_optimal") %>% rename_( "n.Factors" = "n_optimal", "n.Methods" = "n_method" ) %>% - mutate_("n.Factors" = ~ as.integer(n.Factors)) %>% + mutate_("n.Factors" = ~as.integer(n.Factors)) %>% left_join(eigenvalues, by = "n.Factors") %>% select_("-Exp.Variance") @@ -277,7 +277,7 @@ n_factors <- function(df, rotate="varimax", fm="minres", n=NULL) { size = 1 ) + scale_y_continuous(sec.axis = sec_axis( - trans = ~ . * (max(plot_data$Cum.Variance) / max(plot_data$Eigenvalues)), + trans = ~. * (max(plot_data$Cum.Variance) / max(plot_data$Eigenvalues)), name = "Cumulative Variance\n" )) + ylab("Eigenvalues\n") + diff --git a/R/odds_to_probs.R b/R/odds_to_probs.R index 6d5f6b0..84bcbed 100644 --- a/R/odds_to_probs.R +++ b/R/odds_to_probs.R @@ -16,7 +16,7 @@ #' #' @importFrom purrr keep discard #' @export -odds_to_probs <- function(odds, subset=NULL, except=NULL, log=TRUE) { +odds_to_probs <- function(odds, subset = NULL, except = NULL, log = TRUE) { # If vector if (ncol(as.matrix(odds)) == 1) { @@ -74,7 +74,7 @@ odds_to_probs <- function(odds, subset=NULL, except=NULL, log=TRUE) { #' @keywords internal -.odds_to_probs <- function(odds, log=TRUE) { +.odds_to_probs <- function(odds, log = TRUE) { if (log == TRUE) { odds <- exp(odds) } diff --git a/R/power_analysis.R b/R/power_analysis.R index 3316d64..9dc3ceb 100644 --- a/R/power_analysis.R +++ b/R/power_analysis.R @@ -39,7 +39,7 @@ #' @importFrom stats model.frame #' @import dplyr #' @export -power_analysis <- function(fit, n_max, n_min=NULL, step=1, n_batch=1, groups=NULL, verbose=TRUE, CI=90, effsize=FALSE, effsize_rules="cohen1988", bayes_factor=FALSE, overlap=FALSE) { +power_analysis <- function(fit, n_max, n_min = NULL, step = 1, n_batch = 1, groups = NULL, verbose = TRUE, CI = 90, effsize = FALSE, effsize_rules = "cohen1988", bayes_factor = FALSE, overlap = FALSE) { # Parameters df <- model.frame(fit) diff --git a/R/probs_to_odds.R b/R/probs_to_odds.R index 0343baa..211172b 100644 --- a/R/probs_to_odds.R +++ b/R/probs_to_odds.R @@ -11,7 +11,7 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -probs_to_odds <- function(probs, log=FALSE) { +probs_to_odds <- function(probs, log = FALSE) { # If vector if (ncol(as.matrix(probs)) == 1) { @@ -23,7 +23,7 @@ probs_to_odds <- function(probs, log=FALSE) { #' @keywords internal -.probs_to_odds <- function(probs, log=FALSE) { +.probs_to_odds <- function(probs, log = FALSE) { odds <- probs / (1 - probs) if (log == TRUE) { odds <- log(odds) diff --git a/R/refdata.R b/R/refdata.R index 3abdb01..4f1b476 100644 --- a/R/refdata.R +++ b/R/refdata.R @@ -22,7 +22,7 @@ #' @importFrom purrr keep #' @import tidyr #' @export -refdata <- function(df, target="all", length.out=10, factors="reference", numerics="mean") { +refdata <- function(df, target = "all", length.out = 10, factors = "reference", numerics = "mean") { # Target if (all(target == "all") | ncol(df) == 1) { @@ -98,7 +98,7 @@ refdata <- function(df, target="all", length.out=10, factors="reference", numeri #' @keywords internal -.refdata_target <- function(target, length.out=10) { +.refdata_target <- function(target, length.out = 10) { at_vars <- names(target) at_df <- data.frame() for (var in at_vars) { @@ -130,10 +130,10 @@ refdata <- function(df, target="all", length.out=10, factors="reference", numeri #' @keywords internal -.refdata_var <- function(x, length.out=10, varname=NULL) { +.refdata_var <- function(x, length.out = 10, varname = NULL) { if (is.numeric(x)) { - out <- data.frame(seq(min(x, na.rm=TRUE), - max(x, na.rm=TRUE), + out <- data.frame(seq(min(x, na.rm = TRUE), + max(x, na.rm = TRUE), length.out = length.out )) } else if (is.factor(x)) { diff --git a/R/rnorm_perfect.R b/R/rnorm_perfect.R index 155be8b..f55e1e7 100644 --- a/R/rnorm_perfect.R +++ b/R/rnorm_perfect.R @@ -18,7 +18,7 @@ #' #' @importFrom stats rnorm #' @export -rnorm_perfect <- function(n, mean = 0, sd = 1, method="qnorm", iter=10000) { +rnorm_perfect <- function(n, mean = 0, sd = 1, method = "qnorm", iter = 10000) { if (method == "average") { x <- rowMeans(replicate(iter, sort(rnorm(n, mean, sd)))) } else { diff --git a/R/rope.R b/R/rope.R index b1a22c6..d8e076e 100644 --- a/R/rope.R +++ b/R/rope.R @@ -20,7 +20,7 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -rope <- function(posterior, bounds=c(-0.1, 0.1), CI=95, overlap=FALSE) { +rope <- function(posterior, bounds = c(-0.1, 0.1), CI = 95, overlap = FALSE) { # Basic rope -------------------------------------------------------------- diff --git a/R/simulate.R b/R/simulate.R index 48ea827..fd6f3d9 100644 --- a/R/simulate.R +++ b/R/simulate.R @@ -19,7 +19,7 @@ #' @author TPArrow #' #' @export -simulate_data_regression <- function(coefs=0.5, sample=100, error=0){ +simulate_data_regression <- function(coefs = 0.5, sample = 100, error = 0) { # Prevent error coefs[coefs == 0] <- 0.01 @@ -27,7 +27,7 @@ simulate_data_regression <- function(coefs=0.5, sample=100, error=0){ y <- rnorm(sample, 0, 1) n_var <- length(coefs) - X <- scale(matrix(rnorm(sample*(n_var), 0, 1), ncol=n_var)) + X <- scale(matrix(rnorm(sample * (n_var), 0, 1), ncol = n_var)) X <- cbind(y, X) # find the current correlation matrix @@ -36,15 +36,15 @@ simulate_data_regression <- function(coefs=0.5, sample=100, error=0){ # cholesky decomposition to get independence chol_0 <- solve(chol(cor_0)) - X <- X %*% chol_0 + X <- X %*% chol_0 # create new correlation structure (zeros can be replaced with other r vals) - coefs_structure <- diag(x = 1, nrow=n_var+1, ncol=n_var+1, names = TRUE) + coefs_structure <- diag(x = 1, nrow = n_var + 1, ncol = n_var + 1, names = TRUE) coefs_structure[-1, 1] <- coefs coefs_structure[1, -1] <- coefs X <- X %*% chol(coefs_structure) * sd(y) + mean(y) - X <- X[,-1] + X <- X[, -1] # Add noise y <- y + rnorm(sample, 0, error) diff --git a/R/standardize.R b/R/standardize.R index d73bfa2..d5428c8 100644 --- a/R/standardize.R +++ b/R/standardize.R @@ -59,7 +59,7 @@ standardize <- function(x, ...) { #' #' #' @export -standardize.numeric <- function(x, normalize=FALSE, ...) { +standardize.numeric <- function(x, normalize = FALSE, ...) { if (all(is.na(x)) | length(unique(x)) == 2) { return(x) } @@ -131,7 +131,7 @@ standardize.numeric <- function(x, normalize=FALSE, ...) { #' @importFrom purrr keep discard #' @import dplyr #' @export -standardize.data.frame <- function(x, subset=NULL, except=NULL, normalize=FALSE, ...) { +standardize.data.frame <- function(x, subset = NULL, except = NULL, normalize = FALSE, ...) { if (inherits(x, "grouped_df")) { dfZ <- x %>% dplyr::do_(".standardize_df(., subset=subset, except=except, normalize=normalize, ...)") } else { @@ -158,7 +158,7 @@ standardize.data.frame <- function(x, subset=NULL, except=NULL, normalize=FALSE, #' @keywords internal -.standardize_df <- function(x, subset=NULL, except=NULL, normalize=FALSE, ...) { +.standardize_df <- function(x, subset = NULL, except = NULL, normalize = FALSE, ...) { df <- x # Variable order @@ -246,7 +246,7 @@ standardize.data.frame <- function(x, subset=NULL, except=NULL, normalize=FALSE, #' #' @importFrom utils capture.output #' @export -standardize.stanreg <- function(x, method="refit", ...) { +standardize.stanreg <- function(x, method = "refit", ...) { fit <- x predictors <- get_info(fit)$predictors @@ -313,7 +313,7 @@ standardize.stanreg <- function(x, method="refit", ...) { #' @seealso https://think-lab.github.io/d/205/ #' #' @export -standardize.glm <- function(x, method="refit", ...) { +standardize.glm <- function(x, method = "refit", ...) { fit <- x if (method == "agresti") { @@ -321,7 +321,6 @@ standardize.glm <- function(x, method="refit", ...) { X <- as.matrix(model.matrix(fit)[, -1]) # -1 to drop column of 1s for intercept sd_X <- sd(X, na.rm = TRUE) coefs <- coefs * sd_X - } else { # refit method data <- get_data(fit) @@ -370,7 +369,7 @@ standardize.glmerMod <- standardize.glm #' @importFrom stats model.frame model.response model.matrix #' #' @export -standardize.lm <- function(x, method="refit", partial_sd=FALSE, preserve_factors=TRUE, ...) { +standardize.lm <- function(x, method = "refit", partial_sd = FALSE, preserve_factors = TRUE, ...) { fit <- x if (method == "posthoc") { @@ -448,7 +447,7 @@ standardize.lmerMod <- standardize.lm #' @importFrom stats nobs vcov #' @keywords internal -.standardize_coefs <- function(fit, partial_sd = FALSE, preserve_factors=TRUE, ...) { +.standardize_coefs <- function(fit, partial_sd = FALSE, preserve_factors = TRUE, ...) { # coefs <- MuMIn::coefTable(fit, ...) coefs <- as.data.frame(MuMIn::coefTable(fit)) model_matrix <- model.matrix(fit) diff --git a/R/summary.psychobject.R b/R/summary.psychobject.R index 50c9949..8c39880 100644 --- a/R/summary.psychobject.R +++ b/R/summary.psychobject.R @@ -10,7 +10,7 @@ #' #' @method summary psychobject #' @export -summary.psychobject <- function(object, round=NULL, ...) { +summary.psychobject <- function(object, round = NULL, ...) { summary <- object$summary if (!is.null(round)) { diff --git a/docs/_posts/2018-05-01-repeated_measure_anovas.md b/docs/_posts/2018-05-01-repeated_measure_anovas.md index 62028d2..c2109c8 100644 --- a/docs/_posts/2018-05-01-repeated_measure_anovas.md +++ b/docs/_posts/2018-05-01-repeated_measure_anovas.md @@ -187,8 +187,8 @@ anova(fit) It seems that there is a significant main effect of the emotion condition, as well as an interaction with the participants' sex. Let's plot the estimated means. ``` r -results <- get_contrasts(fit, "Emotion_Condition * Participant_Sex") -print(results$means) +estimated_means <- get_means(fit, "Emotion_Condition * Participant_Sex") +estimated_means ``` | Emotion\_Condition | Participant\_Sex | Mean| SE| df| CI\_lower| CI\_higher| @@ -199,7 +199,7 @@ print(results$means) | Neutral | Male | 12.89| 6.35| 23.3| -0.24| 26.02| ``` r -ggplot(results$means, aes(x=Emotion_Condition, y=Mean, color=Participant_Sex, group=Participant_Sex)) + +ggplot(estimated_means, aes(x=Emotion_Condition, y=Mean, color=Participant_Sex, group=Participant_Sex)) + geom_line(position = position_dodge(.3)) + geom_pointrange(aes(ymin=CI_lower, ymax=CI_higher), position = position_dodge(.3)) + @@ -213,7 +213,7 @@ ggplot(results$means, aes(x=Emotion_Condition, y=Mean, color=Participant_Sex, gr Let's investigate the contrasts: ``` r -print(results$contrasts) +get_contrasts(fit, "Emotion_Condition * Participant_Sex") ``` | Contrast | Difference| SE| df| t.ratio| p.value| @@ -228,8 +228,7 @@ print(results$contrasts) It appears that the differences between men and women is not significant. However, by default, `get_contrasts` uses the Tukey method for p value adjustment. We can, with an exploratory mindset, **turn off the p value correction** (or choose other methods such as *bonferonni*, *fdr* and such). ``` r -results <- get_contrasts(fit, "Emotion_Condition * Participant_Sex", adjust = "none") -print(results$contrasts) +get_contrasts(fit, "Emotion_Condition * Participant_Sex", adjust = "none") ``` | Contrast | Difference| SE| df| t.ratio| p.value| diff --git a/docs/~$index.html b/docs/~$index.html deleted file mode 100644 index dbf56053ba1df5f78a217c172771146e9a6dab72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 zcmd;d@lDLmFE7r{WFP@>GPp4KG9)r&GvqUrGZX`9i1tepUf*G`Vd&V9bbgisBLf4B ph8cZj!pl1hwhSE?pz<&pCVy>$_#Fm2hAu9KD4@wD45 Date: Wed, 7 Nov 2018 16:32:43 +0100 Subject: [PATCH 11/17] added `plot_lavaan` --- NAMESPACE | 1 + R/analyze.lavaan.R | 191 ++++++++++++++++++++++++++++------- R/get_predicted.merMod.R | 14 ++- R/get_predicted.stanreg.R | 23 +++-- man/analyze.lavaan.Rd | 6 +- man/get_predicted.merMod.Rd | 6 +- man/get_predicted.stanreg.Rd | 5 +- man/plot_lavaan.Rd | 30 ++++++ vignettes/bayesian.Rmd | 6 +- 9 files changed, 221 insertions(+), 61 deletions(-) create mode 100644 man/plot_lavaan.Rd diff --git a/NAMESPACE b/NAMESPACE index 64c70ed..4555c7e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -123,6 +123,7 @@ export(omega_sq) export(overlap) export(percentile) export(percentile_to_z) +export(plot_lavaan) export(plot_loadings) export(power_analysis) export(probs_to_odds) diff --git a/R/analyze.lavaan.R b/R/analyze.lavaan.R index fdb1237..8464a1d 100644 --- a/R/analyze.lavaan.R +++ b/R/analyze.lavaan.R @@ -1,8 +1,8 @@ -#' Analyze aov objects. +#' Analyze lavaan (SEM or CFA) objects. #' -#' Analyze aov objects. +#' Analyze lavaan (SEM or CFA) objects. #' -#' @param x aov object. +#' @param x lavaan object. #' @param ... Arguments passed to or from other methods. #' #' @return output @@ -30,16 +30,44 @@ #' #' @export analyze.lavaan <- function(x, ...) { + fit <- x - # TODO: this must be enhanced! # Processing # ------------- + values <- list() + + # Fit measures + values$Fit_Measures <- .interpret_fitmeasures(fit) + + + + # Summary + # ------------- + summary <- .summary_lavaan(fit) + + # Plot + # ------------- + plot <- "Use `plot_lavaan` in association with ggraph." + + output <- list(text = values$Fit_Measures$text, plot = plot, summary = summary, values = values) - # TODO: tWait for broom to implement methods for lavaan objects! + class(output) <- c("psychobject", "list") + return(output) +} + + + + + + +#' @keywords internal +.interpret_fitmeasures <- function(fit){ values <- list() - indices <- lavaan::fitmeasures(x) + indices <- lavaan::fitmeasures(fit) + + for (index in names(indices)) { values[index] <- indices[index] } @@ -71,20 +99,18 @@ analyze.lavaan <- function(x, ...) { } else { nfi <- "poor" } - fit <- data.frame( + + # Summary + summary <- data.frame( Index = c("RMSEA", "CFI", "GFI", "TLI", "NFI", "Chisq"), Value = c(values$rmsea, values$cfi, values$gfi, values$tli, values$nfi, values$chisq), Interpretation = c(rmsea, cfi, gfi, tli, nfi, NA), Treshold = c("< .08", "> .90", "> 0.90", "> 0.90", "> 0.90", NA) ) - - - # Text - # ------------- - if ("satisfactory" %in% fit$Interpretation) { - satisfactory <- fit %>% + if ("satisfactory" %in% summary$Interpretation) { + satisfactory <- summary %>% filter_("Interpretation == 'satisfactory'") %>% mutate_("Index" = "paste0(Index, ' (', format_digit(Value), ' ', Treshold, ')')") %>% select_("Index") %>% @@ -94,8 +120,8 @@ analyze.lavaan <- function(x, ...) { } else { satisfactory <- "" } - if ("poor" %in% fit$Interpretation) { - poor <- fit %>% + if ("poor" %in% summary$Interpretation) { + poor <- summary %>% filter_("Interpretation == 'poor'") %>% mutate_( "Treshold" = 'stringr::str_replace(Treshold, "<", "SUP")', @@ -113,30 +139,121 @@ analyze.lavaan <- function(x, ...) { } text <- paste(satisfactory, poor) + output <- list(text = text, summary = summary, values = values, plot="Not available yet") + class(output) <- c("psychobject", "list") + return(output) - # Summary - # ------------- - summary <- lavaan::parameterEstimates(x) %>% - as_data_frame() %>% - tibble::rownames_to_column() %>% - mutate_("term" = "paste(lhs, op, rhs)") %>% - rename( - "estimate" = "est", - "Operator" = "op", - "std.error" = "se", - "p.value" = "pvalue", - "statistic" = "z", - "CI_lower" = "ci.lower", - "CI_upper" = "ci.upper" - ) %>% - select_("term", "Operator", "everything()", "-rowname", "-lhs", "-rhs") +} - # Plot - # ------------- - plot <- "Not available yet" - output <- list(text = text, plot = plot, summary = summary, values = values) - class(output) <- c("psychobject", "list") - return(output) + + + + + + + + +#' @keywords internal +.summary_lavaan <- function(fit, standardized=TRUE){ + + if(standardized == TRUE){ + solution <- lavaan::standardizedSolution(fit) + } else{ + solution <- lavaan::parameterEstimates(fit) + } + + + solution <- solution %>% + rename("From" = "rhs", + "To" = "lhs", + "Operator" = "op", + "Coef" = "est.std", + "SE" = "se", + "p" = "pvalue", + "CI_lower" = "ci.lower", + "CI_higher" = "ci.upper") %>% + mutate(Type = dplyr::case_when( + Operator == "=~" ~ "Loading", + Operator == "~" ~ "Regression", + Operator == "~~" ~ "Correlation", + TRUE ~ NA)) + + return(solution) } + + + + + + + +#' Plot lavaan (SEM or CFA) objects. +#' +#' Plot lavaan (SEM or CFA) objects. +#' +#' @param fit lavaan object. +#' @param links Which links to include? A list including at least one of "Regression", "Loading" or "Correlation". +#' @param threshold_p Omit all links with a p value below this value. +#' @param threshold_Coef Omit all links with a Coefs below this value. +#' @param digits Edges' labels rounding. +#' +#' @return A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @seealso +#' https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM +#' +#' +#' @export +plot_lavaan <- function(fit, links=c("Regression"), threshold_p=NULL, threshold_Coef=NULL, digits=2){ +# https://www.r-bloggers.com/ggplot2-sem-models-with-tidygraph-and-ggraph/ + + summary <- summary(analyze(fit)) + + # Sanitize + if(is.null(threshold_p)){ + threshold_p <- 1.1 + } + if(is.null(threshold_Coef)){ + threshold_Coef <- max(abs(summary$Coef)) + } + + # Edge properties + edges <- summary %>% + filter_('Type %in% c(links)', + "From != To", + "p < threshold_p", + "abs(Coef) < threshold_Coef") %>% + rename_("to" = "To", + "from" = "From") %>% + mutate_('Label_Regression' = "ifelse(Type=='Regression', round(Coef, digits), '')", + 'Label_Correlation' = "ifelse(Type=='Correlation', round(Coef, digits), '')", + 'Label_Loading' = "ifelse(Type=='Loading', round(Coef, digits), '')") + edges <- edges[colSums(!is.na(edges)) > 0] + + # Identify latent variables for nodes + latent_nodes <- edges %>% + filter_('Type == "Loading"') %>% + distinct_("to") %>% + transmute_("metric" = "to", "latent" = TRUE) + + nodes_list <- unique(c(edges$from, edges$to)) + + # Node properties + nodes <- summary %>% + filter_("From == To", + "From %in% nodes_list") %>% + mutate_("metric" = "From") %>% + left_join(latent_nodes, by="metric") %>% + mutate_("latent" = "if_else(is.na(latent), FALSE, latent)") + + return(output = list(nodes = nodes, edges = edges)) +} + + + + diff --git a/R/get_predicted.merMod.R b/R/get_predicted.merMod.R index c7ff39a..7223d0b 100644 --- a/R/get_predicted.merMod.R +++ b/R/get_predicted.merMod.R @@ -8,7 +8,7 @@ #' @param odds_to_probs Transform log odds ratios in logistic models to probabilies. #' @param iter An integer indicating the number of iterations for bootstrapping (when prob is not null). #' @param seed An optional seed to use. -#' @param re.form Formula for random effects to condition on. If NULL, include all random effects; if NA or ~0, include no random effects (see \link[lme4]{predict.merMod}). +#' @param re.form Formula for random effects to condition on. If NULL, include all random effects; if NA or ~0, include no random effects (see \link[lme4]{predict.merMod}). If "default", then will ne NULL if the random are present in the data, and NA if not. #' @param use.u logical, indicating whether the spherical random effects should be simulated / bootstrapped as well. If TRUE, they are not changed, and all inference is conditional on these values. If FALSE, new normal deviates are drawn (see\link[lme4]{bootMer}). #' @param ... Arguments passed to or from other methods. #' @@ -61,7 +61,7 @@ #' @importFrom dplyr bind_cols #' @importFrom tibble rownames_to_column #' @export -get_predicted.merMod <- function(fit, newdata="model", prob=NULL, odds_to_probs=TRUE, iter=100, seed=NULL, re.form=NULL, use.u=FALSE, ...) { +get_predicted.merMod <- function(fit, newdata="model", prob=NULL, odds_to_probs=TRUE, iter=100, seed=NULL, re.form="default", use.u=FALSE, ...) { # Extract names @@ -87,7 +87,15 @@ get_predicted.merMod <- function(fit, newdata="model", prob=NULL, odds_to_probs= } - + # Deal with random + if(re.form=="default"){ + # Check if all predictors are in variables + if(all(get_info(fit)$predictors %in% names(newdata))){ + re.form <- NULL + } else{ + re.form <- NA + } + } diff --git a/R/get_predicted.stanreg.R b/R/get_predicted.stanreg.R index 393227f..f40ff34 100644 --- a/R/get_predicted.stanreg.R +++ b/R/get_predicted.stanreg.R @@ -11,6 +11,7 @@ #' @param posterior_predict Posterior draws of the outcome instead of the link function (i.e., the regression "line"). #' @param seed An optional seed to use. #' @param transform If posterior_predict is False, should the linear predictor be transformed using the inverse-link function? The default is FALSE, in which case the untransformed linear predictor is returned. +#' @param re.form If object contains group-level parameters, a formula indicating which group-level parameters to condition on when making predictions. re.form is specified in the same form as for predict.merMod. NULL indicates that all estimated group-level parameters are conditioned on. To refrain from conditioning on any group-level parameters, specify NA or ~0. The newdata argument may include new levels of the grouping factors that were specified when the model was estimated, in which case the resulting posterior predictions marginalize over the relevant variables (see \link[rstanarm]{posterior_predict.stanreg}). If "default", then will ne NULL if the random are present in the data, and NA if not. #' @param ... Arguments passed to or from other methods. #' #' @@ -53,7 +54,7 @@ #' @importFrom dplyr bind_cols #' @importFrom tibble rownames_to_column #' @export -get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_probs = TRUE, keep_iterations = FALSE, draws = NULL, posterior_predict = FALSE, seed = NULL, transform = FALSE, ...) { +get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_probs = TRUE, keep_iterations = FALSE, draws = NULL, posterior_predict = FALSE, seed = NULL, transform = FALSE, re.form="default", ...) { # Extract names predictors <- all.vars(as.formula(fit$formula)) @@ -66,14 +67,6 @@ get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_pr newdata[".wgt."] <- NULL } - # Deal with potential random - re.form <- NULL - if (!is.null(newdata)) { - if (!is.character(newdata) & is.mixed(fit)) { - re.form <- NA - } - } - # Set newdata to actual data original_data <- FALSE if (!is.null(newdata)) { @@ -86,6 +79,18 @@ get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_pr } } + # Deal with potential random + if(re.form=="default"){ + if(is.mixed(fit)){ + # Check if all predictors are in variables + if(all(get_info(fit)$predictors %in% names(newdata))){ + re.form <- NULL + } else{ + re.form <- NA + } + } + } + # Generate draws ------------------------------------------------------- if (posterior_predict == FALSE) { posterior <- rstanarm::posterior_linpred(fit, newdata = newdata, re.form = re.form, seed = seed, draws = draws, transform = transform) diff --git a/man/analyze.lavaan.Rd b/man/analyze.lavaan.Rd index 3f85018..4fec644 100644 --- a/man/analyze.lavaan.Rd +++ b/man/analyze.lavaan.Rd @@ -2,12 +2,12 @@ % Please edit documentation in R/analyze.lavaan.R \name{analyze.lavaan} \alias{analyze.lavaan} -\title{Analyze aov objects.} +\title{Analyze lavaan (SEM or CFA) objects.} \usage{ \method{analyze}{lavaan}(x, ...) } \arguments{ -\item{x}{aov object.} +\item{x}{lavaan object.} \item{...}{Arguments passed to or from other methods.} } @@ -15,7 +15,7 @@ output } \description{ -Analyze aov objects. +Analyze lavaan (SEM or CFA) objects. } \examples{ library(psycho) diff --git a/man/get_predicted.merMod.Rd b/man/get_predicted.merMod.Rd index ff3f2c8..1485d32 100644 --- a/man/get_predicted.merMod.Rd +++ b/man/get_predicted.merMod.Rd @@ -5,8 +5,8 @@ \title{Compute predicted values of lm models.} \usage{ \method{get_predicted}{merMod}(fit, newdata = "model", prob = NULL, - odds_to_probs = TRUE, iter = 100, seed = NULL, re.form = NULL, - use.u = FALSE, ...) + odds_to_probs = TRUE, iter = 100, seed = NULL, + re.form = "default", use.u = FALSE, ...) } \arguments{ \item{fit}{An lm model.} @@ -21,7 +21,7 @@ \item{seed}{An optional seed to use.} -\item{re.form}{Formula for random effects to condition on. If NULL, include all random effects; if NA or ~0, include no random effects (see \link[lme4]{predict.merMod}).} +\item{re.form}{Formula for random effects to condition on. If NULL, include all random effects; if NA or ~0, include no random effects (see \link[lme4]{predict.merMod}). If "default", then will ne NULL if the random are present in the data, and NA if not.} \item{use.u}{logical, indicating whether the spherical random effects should be simulated / bootstrapped as well. If TRUE, they are not changed, and all inference is conditional on these values. If FALSE, new normal deviates are drawn (see\link[lme4]{bootMer}).} diff --git a/man/get_predicted.stanreg.Rd b/man/get_predicted.stanreg.Rd index 20bf1fa..fc2d951 100644 --- a/man/get_predicted.stanreg.Rd +++ b/man/get_predicted.stanreg.Rd @@ -6,7 +6,8 @@ \usage{ \method{get_predicted}{stanreg}(fit, newdata = "model", prob = 0.9, odds_to_probs = TRUE, keep_iterations = FALSE, draws = NULL, - posterior_predict = FALSE, seed = NULL, transform = FALSE, ...) + posterior_predict = FALSE, seed = NULL, transform = FALSE, + re.form = "default", ...) } \arguments{ \item{fit}{A stanreg model.} @@ -27,6 +28,8 @@ \item{transform}{If posterior_predict is False, should the linear predictor be transformed using the inverse-link function? The default is FALSE, in which case the untransformed linear predictor is returned.} +\item{re.form}{If object contains group-level parameters, a formula indicating which group-level parameters to condition on when making predictions. re.form is specified in the same form as for predict.merMod. NULL indicates that all estimated group-level parameters are conditioned on. To refrain from conditioning on any group-level parameters, specify NA or ~0. The newdata argument may include new levels of the grouping factors that were specified when the model was estimated, in which case the resulting posterior predictions marginalize over the relevant variables (see \link[rstanarm]{posterior_predict.stanreg}). If "default", then will ne NULL if the random are present in the data, and NA if not.} + \item{...}{Arguments passed to or from other methods.} } \value{ diff --git a/man/plot_lavaan.Rd b/man/plot_lavaan.Rd new file mode 100644 index 0000000..78c4814 --- /dev/null +++ b/man/plot_lavaan.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/analyze.lavaan.R +\name{plot_lavaan} +\alias{plot_lavaan} +\title{Plot lavaan (SEM or CFA) objects.} +\usage{ +plot_lavaan(fit, links = c("Regression"), threshold_p = NULL, + threshold_Coef = NULL) +} +\arguments{ +\item{fit}{lavaan object.} + +\item{links}{Which links to include? A list including at least one of "Regression", "Loading" or "Correlation".} + +\item{threshold_p}{Omit all links with a p value below this value.} + +\item{threshold_Coef}{Omit all links with a Coefs below this value.} +} +\value{ +A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. +} +\description{ +Plot lavaan (SEM or CFA) objects. +} +\seealso{ +https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/vignettes/bayesian.Rmd b/vignettes/bayesian.Rmd index b4f4a44..295d3c9 100644 --- a/vignettes/bayesian.Rmd +++ b/vignettes/bayesian.Rmd @@ -462,10 +462,6 @@ Relationships in the real world are often non-linear. For example, based on the ### Model Exploration -```{r, message=FALSE, results="hide", warning=FALSE, eval=FALSE} -# Let's fit our model (it takes more time) -fit <- rstanarm::stan_lmer(Concealing ~ poly(Age, 2, raw=TRUE) + (1|Salary), data=df) -``` ```{r message=FALSE, warning=FALSE, include=FALSE, results="hide"} # Let's fit our model (it takes more time) fit <- rstanarm::stan_lmer(Concealing ~ poly(Age, 2, raw=TRUE) + (1|Salary), data=df, iter=500, chains=2) @@ -480,7 +476,7 @@ results <- psycho::analyze(fit) summary(results, round = 2) ``` ```{r echo=FALSE, message=FALSE, warning=FALSE} -kable(summary(results, round = 2)) +knitr::kable(summary(results, round = 2)) ``` As we can see, both the linear relationship and the second order curvature are highly probable. However, when setting `raw=TRUE` in the formula, the coefficients become unintepretable. So let's visualize them. From 7b33aa5bba94a3e772280b0734f4b5e94dfc6b24 Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Wed, 7 Nov 2018 20:56:47 +0100 Subject: [PATCH 12/17] start `analyze.blavaan` --- R/analyze.blavaan.R | 284 ++++++++++++++++++++++++++++++++++++++++++++ R/analyze.lavaan.R | 28 ++--- R/analyze.stanreg.R | 2 +- 3 files changed, 298 insertions(+), 16 deletions(-) create mode 100644 R/analyze.blavaan.R diff --git a/R/analyze.blavaan.R b/R/analyze.blavaan.R new file mode 100644 index 0000000..576ac54 --- /dev/null +++ b/R/analyze.blavaan.R @@ -0,0 +1,284 @@ +#' Analyze lavaan (SEM or CFA) objects. +#' +#' Analyze lavaan (SEM or CFA) objects. +#' +#' @param x lavaan object. +#' @param ... Arguments passed to or from other methods. +#' +#' @return output +#' +#' @examples +#' library(psycho) +#' library(lavaan) +#' +#' model <- ' visual =~ x1 + x2 + x3 +#' textual =~ x4 + x5 + x6 +#' speed =~ x7 + x8 + x9 ' +#' x <- lavaan::cfa(model, data=HolzingerSwineford1939) +#' +#' rez <- analyze(x) +#' print(rez) +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @seealso +#' https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM +#' +#' +#' @importFrom lavaan parameterEstimates fitmeasures +#' +#' @export +analyze.lavaan <- function(x, ...) { + fit <- x + + + + + # Processing + # ------------- + values <- list() + + # Fit measures + values$Fit_Measures <- .interpret_fitmeasures(fit) + + # Summary + # ------------- + summary <- .summary_lavaan(fit) + + # Plot + # ------------- + plot <- "Use `plot_lavaan` in association with ggraph." + + output <- list(text = values$Fit_Measures$text, plot = plot, summary = summary, values = values) + + class(output) <- c("psychobject", "list") + return(output) +} + + + + + + +#' @keywords internal +.interpret_fitmeasures.blavaan <- function(fit, indices=c("BIC", "DIC", "WAIC", "LOOIC")){ + values <- list() + + indices <- fitmeasures(fit) + + + for (index in names(indices)) { + values[index] <- indices[index] + } + + # Summary + summary <- as.data.frame(indices) %>% + rownames_to_column("Index") %>% + rename_("Value" = "indices") %>% + mutate_("Index" = "str_to_upper(Index)") + + # Text + relevant_indices <- summary[summary$Index %in% c("BIC", "DIC", "WAIC", "LOOIC"),] + text <- paste0(relevant_indices$Index, " = ", format_digit(relevant_indices$Value), collapse=", ") + + output <- list(text = text, summary = summary, values = values, plot="Not available yet") + class(output) <- c("psychobject", "list") + return(output) + +} + + + +#' @keywords internal +.get_info_computations.blavaan <- function(fit) { + chains <- blavInspect(fit, "n.chains") + sample = fit@external$sample + warmup = fit@external$burnin + text = paste0(chains, + "chains, each with iter = ", + sample, + "; warmup = ", + warmup) + return(text) +} + + + + +#' @keywords internal +.process_blavaan <- function(fit, CI=90){ + # Get relevant rows + PE <- parameterEstimates(fit, se = FALSE, ci=FALSE, remove.eq = FALSE, remove.system.eq = TRUE, + remove.ineq = FALSE, remove.def = FALSE, + add.attributes = TRUE) + if(!("group" %in% names(PE))) PE$group <- 1 + newpt <- fit@ParTable + pte2 <- which(newpt$free > 0) + relevant_rows <- match(with(newpt, paste(lhs[pte2], op[pte2], rhs[pte2], group[pte2], sep="")), + paste(PE$lhs, PE$op, PE$rhs, PE$group, sep="")) + + # Priors + priors <- rep(NA, nrow(PE)) + priors[relevant_rows] <- newpt$prior[pte2] + priors[is.na(PE$prior)] <- "" + + # Posterior + posteriors <- blavInspect(fit, "draws") %>% + as.matrix() %>% + as.data.frame() + names(posteriors) <- names(coef(fit)) + + + # Effects + MPE <- c() + Median <- c() + MAD <- c() + Effect <- c() + CI_lower <- c() + CI_higher <- c() + for(effect in names(posteriors)){ + posterior <- posteriors[[effect]] + Effect <- c(Effect, effect) + MPE <- c(MPE, mpe(posterior)$MPE) + Median <- c(Median, median(posterior)) + MAD <- c(MAD, mad(posterior)) + + CI_values <- HDI(posterior, prob = CI / 100) + CI_lower <- c(CI_lower, CI_values$values$HDImin) + CI_higher <- c(CI_higher, CI_values$values$HDImax) + + } + + Effects <- rep(NA, nrow(PE)) + Effects[relevant_rows] <- Effect + MPEs <- rep(NA, nrow(PE)) + MPEs[relevant_rows] <- MPE + Medians <- rep(NA, nrow(PE)) + Medians[relevant_rows] <- Median + MADs <- rep(NA, nrow(PE)) + MADs[relevant_rows] <- MAD + CI_lowers <- rep(NA, nrow(PE)) + CI_lowers[relevant_rows] <- CI_lower + CI_highers <- rep(NA, nrow(PE)) + CI_highers[relevant_rows] <- CI_higher + + data <- data.frame("Effect" = Effects, + "Median" = Medians, + "MAD" = MADs, + "MPE" = MPEs, + "CI_lower" = CI_lowers, + "CI_higher" = CI_highers, + "Prior" = priors) + + return(data) +} + + + +#' @keywords internal +.summary_lavaan <- function(fit){ + + solution <- parameterEstimates(fit, se = TRUE, ci=TRUE, standardized=TRUE) + + + solution <- solution %>% + rename("From" = "rhs", + "To" = "lhs", + "Operator" = "op", + "Coef" = "est", + "Coef_std" = "std.all", + "SE" = "se", + "CI_lower" = "ci.lower", + "CI_higher" = "ci.upper") %>% + mutate(Type = dplyr::case_when( + Operator == "=~" ~ "Loading", + Operator == "~" ~ "Regression", + Operator == "~~" ~ "Correlation", + TRUE ~ NA_character_)) %>% + select(one_of(c("To", "Operator", "From", "Coef_std", "Type"))) %>% + cbind(.process_blavaan(fit)) %>% + select_("-Effect") %>% + mutate_("Median" = "replace_na(Median, 1)", + "MAD" = "replace_na(MAD, 0)", + "MPE" = "replace_na(MPE, 100)") %>% + select(one_of(c("To", "Operator", "From", "Median", "MAD", "CI_lower", "CI_higher", "MPE", "Coef_std", "Prior", "Type"))) + + + return(solution) +} + + + + + + + +#' Plot lavaan (SEM or CFA) objects. +#' +#' Plot lavaan (SEM or CFA) objects. +#' +#' @param fit lavaan object. +#' @param links Which links to include? A list including at least one of "Regression", "Loading" or "Correlation". +#' @param threshold_p Omit all links with a p value below this value. +#' @param threshold_Coef Omit all links with a Coefs below this value. +#' @param digits Edges' labels rounding. +#' +#' @return A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @seealso +#' https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM +#' +#' +#' @export +plot_lavaan <- function(fit, links=c("Regression"), threshold_p=NULL, threshold_Coef=NULL, digits=2){ +# https://www.r-bloggers.com/ggplot2-sem-models-with-tidygraph-and-ggraph/ + + summary <- summary(analyze(fit)) + + # Sanitize + if(is.null(threshold_p)){ + threshold_p <- 1.1 + } + if(is.null(threshold_Coef)){ + threshold_Coef <- max(abs(summary$Coef)) + } + + # Edge properties + edges <- summary %>% + filter_('Type %in% c(links)', + "From != To", + "p < threshold_p", + "abs(Coef) > threshold_Coef") %>% + rename_("to" = "To", + "from" = "From") %>% + mutate_('Label_Regression' = "ifelse(Type=='Regression', format_digit(Coef, digits), '')", + 'Label_Correlation' = "ifelse(Type=='Correlation', format_digit(Coef, digits), '')", + 'Label_Loading' = "ifelse(Type=='Loading', format_digit(Coef, digits), '')") + edges <- edges[colSums(!is.na(edges)) > 0] + + # Identify latent variables for nodes + latent_nodes <- edges %>% + filter_('Type == "Loading"') %>% + distinct_("to") %>% + transmute_("metric" = "to", "latent" = TRUE) + + nodes_list <- unique(c(edges$from, edges$to)) + + # Node properties + nodes <- summary %>% + filter_("From == To", + "From %in% nodes_list") %>% + mutate_("metric" = "From") %>% + left_join(latent_nodes, by="metric") %>% + mutate_("latent" = "if_else(is.na(latent), FALSE, latent)") + + return(output = list(nodes = nodes, edges = edges)) +} + + + + diff --git a/R/analyze.lavaan.R b/R/analyze.lavaan.R index 8464a1d..70c8871 100644 --- a/R/analyze.lavaan.R +++ b/R/analyze.lavaan.R @@ -62,7 +62,7 @@ analyze.lavaan <- function(x, ...) { #' @keywords internal -.interpret_fitmeasures <- function(fit){ +.interpret_fitmeasures.lavaan <- function(fit){ values <- list() indices <- lavaan::fitmeasures(fit) @@ -156,20 +156,16 @@ analyze.lavaan <- function(x, ...) { #' @keywords internal -.summary_lavaan <- function(fit, standardized=TRUE){ - - if(standardized == TRUE){ - solution <- lavaan::standardizedSolution(fit) - } else{ - solution <- lavaan::parameterEstimates(fit) - } +.summary_lavaan.lavaan <- function(fit){ + solution <- lavaan::parameterEstimates(fit, standardized=TRUE) solution <- solution %>% rename("From" = "rhs", "To" = "lhs", "Operator" = "op", - "Coef" = "est.std", + "Coef" = "est", + "Coef_std" = "std.all", "SE" = "se", "p" = "pvalue", "CI_lower" = "ci.lower", @@ -178,7 +174,9 @@ analyze.lavaan <- function(x, ...) { Operator == "=~" ~ "Loading", Operator == "~" ~ "Regression", Operator == "~~" ~ "Correlation", - TRUE ~ NA)) + TRUE ~ NA_character_)) %>% + mutate_("p" = "replace_na(p, 0)") %>% + select(one_of(c("To", "Operator", "From", "Coef", "SE", "CI_lower", "CI_higher", "p", "Coef_std", "Type"))) return(solution) } @@ -209,7 +207,7 @@ analyze.lavaan <- function(x, ...) { #' #' #' @export -plot_lavaan <- function(fit, links=c("Regression"), threshold_p=NULL, threshold_Coef=NULL, digits=2){ +plot_lavaan.lavaan <- function(fit, links=c("Regression"), threshold_p=NULL, threshold_Coef=NULL, digits=2){ # https://www.r-bloggers.com/ggplot2-sem-models-with-tidygraph-and-ggraph/ summary <- summary(analyze(fit)) @@ -227,12 +225,12 @@ plot_lavaan <- function(fit, links=c("Regression"), threshold_p=NULL, threshold_ filter_('Type %in% c(links)', "From != To", "p < threshold_p", - "abs(Coef) < threshold_Coef") %>% + "abs(Coef) > threshold_Coef") %>% rename_("to" = "To", "from" = "From") %>% - mutate_('Label_Regression' = "ifelse(Type=='Regression', round(Coef, digits), '')", - 'Label_Correlation' = "ifelse(Type=='Correlation', round(Coef, digits), '')", - 'Label_Loading' = "ifelse(Type=='Loading', round(Coef, digits), '')") + mutate_('Label_Regression' = "ifelse(Type=='Regression', format_digit(Coef, digits), '')", + 'Label_Correlation' = "ifelse(Type=='Correlation', format_digit(Coef, digits), '')", + 'Label_Loading' = "ifelse(Type=='Loading', format_digit(Coef, digits), '')") edges <- edges[colSums(!is.na(edges)) > 0] # Identify latent variables for nodes diff --git a/R/analyze.stanreg.R b/R/analyze.stanreg.R index a24b7b0..1cb2a97 100644 --- a/R/analyze.stanreg.R +++ b/R/analyze.stanreg.R @@ -344,7 +344,7 @@ analyze.stanreg <- function(x, CI = 90, index = "overlap", ROPE_bounds = NULL, e #' @keywords internal -.get_info_priors <- function(varname, info_priors, predictors = NULL) { +.get_info_priors.stanreg <- function(varname, info_priors, predictors = NULL) { # Prior # TBD: this doesn't work with categorical predictors :( values <- list() From ab92b5e974ad4481fcf74dc28bf02cad20e46443 Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Fri, 9 Nov 2018 14:15:45 +0100 Subject: [PATCH 13/17] enhancements to lavaan/blavaan processing --- DESCRIPTION | 3 +- NAMESPACE | 8 +- NEWS.md | 6 ++ R/analyze.R | 3 +- R/analyze.blavaan.R | 205 +++++++++++++--------------------------- R/analyze.lavaan.R | 180 ++++------------------------------- R/analyze.stanreg.R | 4 +- R/get_R2.R | 7 +- R/get_graph.R | 187 ++++++++++++++++++++++++++++++++++++ R/interpret_lavaan.R | 133 ++++++++++++++++++++++++++ man/analyze.Rd | 3 +- man/analyze.blavaan.Rd | 43 +++++++++ man/analyze.lavaan.Rd | 8 +- man/analyze.stanreg.Rd | 2 +- man/get_graph.Rd | 23 +++++ man/get_graph.fa.Rd | 26 +++++ man/get_graph.lavaan.Rd | 41 ++++++++ man/interpret_lavaan.Rd | 16 ++++ man/plot_lavaan.Rd | 30 ------ 19 files changed, 583 insertions(+), 345 deletions(-) create mode 100644 R/get_graph.R create mode 100644 R/interpret_lavaan.R create mode 100644 man/analyze.blavaan.Rd create mode 100644 man/get_graph.Rd create mode 100644 man/get_graph.fa.Rd create mode 100644 man/get_graph.lavaan.Rd create mode 100644 man/interpret_lavaan.Rd delete mode 100644 man/plot_lavaan.Rd diff --git a/DESCRIPTION b/DESCRIPTION index bce5228..43601e2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -63,5 +63,6 @@ Suggests: testthat, covr, plotly, - GPArotation + GPArotation, + blavaan (>= 0.3.4) VignetteBuilder: knitr diff --git a/NAMESPACE b/NAMESPACE index 4555c7e..c3333f0 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,7 @@ S3method(analyze,anova) S3method(analyze,aov) S3method(analyze,aovlist) +S3method(analyze,blavaan) S3method(analyze,fa) S3method(analyze,glm) S3method(analyze,glmerMod) @@ -34,6 +35,8 @@ S3method(get_formula,lm) S3method(get_formula,lmerMod) S3method(get_formula,lmerModLmerTest) S3method(get_formula,stanreg) +S3method(get_graph,fa) +S3method(get_graph,lavaan) S3method(get_info,glm) S3method(get_info,glmerMod) S3method(get_info,lm) @@ -50,6 +53,8 @@ S3method(get_predicted,glm) S3method(get_predicted,lm) S3method(get_predicted,merMod) S3method(get_predicted,stanreg) +S3method(interpret_lavaan,blavaan) +S3method(interpret_lavaan,lavaan) S3method(is.mixed,stanreg) S3method(plot,psychobject) S3method(print,psychobject) @@ -94,6 +99,7 @@ export(get_cfa_model) export(get_contrasts) export(get_data) export(get_formula) +export(get_graph) export(get_info) export(get_loadings_max) export(get_means) @@ -105,6 +111,7 @@ export(interpret_RMSEA) export(interpret_bf) export(interpret_d) export(interpret_d_posterior) +export(interpret_lavaan) export(interpret_odds) export(interpret_odds_posterior) export(interpret_omega_sq) @@ -123,7 +130,6 @@ export(omega_sq) export(overlap) export(percentile) export(percentile_to_z) -export(plot_lavaan) export(plot_loadings) export(power_analysis) export(probs_to_odds) diff --git a/NEWS.md b/NEWS.md index 6943fd3..6ebd154 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,12 @@ # Current Dev + + + +# [0.4.0](https://github.com/neuropsychology/psycho.R/releases/tag/0.4.0) (2018-06-11) + ### Breaking changes +- Major release, lots of undocumented breaking changes.) - Changed `hdi` to `HDI` - Removed Mean and SD from summary in `bayes_cor.test` ### New functions / parameters diff --git a/R/analyze.R b/R/analyze.R index b8e1ead..b64b8c2 100644 --- a/R/analyze.R +++ b/R/analyze.R @@ -14,7 +14,8 @@ #' } #' \itemize{ #' \item{\link[=analyze.fa]{analyze.fa}} -#' \item{\link[=analyze.fa]{analyze.lavaan}} +#' \item{\link[=analyze.lavaan]{analyze.lavaan}} +#' \item{\link[=analyze.blavaan]{analyze.blavaan}} #' } #' #' @param x object to analyze. diff --git a/R/analyze.blavaan.R b/R/analyze.blavaan.R index 576ac54..88778bc 100644 --- a/R/analyze.blavaan.R +++ b/R/analyze.blavaan.R @@ -1,8 +1,10 @@ -#' Analyze lavaan (SEM or CFA) objects. +#' Analyze blavaan (SEM or CFA) objects. #' -#' Analyze lavaan (SEM or CFA) objects. +#' Analyze blavaan (SEM or CFA) objects. #' #' @param x lavaan object. +#' @param CI Credible interval level. +#' @param standardize Compute standardized coefs. #' @param ... Arguments passed to or from other methods. #' #' @return output @@ -25,30 +27,38 @@ #' @seealso #' https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM #' -#' #' @importFrom lavaan parameterEstimates fitmeasures #' #' @export -analyze.lavaan <- function(x, ...) { +analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { fit <- x - - # Processing # ------------- values <- list() + values$CI = CI # Fit measures - values$Fit_Measures <- .interpret_fitmeasures(fit) + values$Fit_Measures <- interpret_lavaan(fit) + + + # Text + # ------------- + computations <- .get_info_computations(fit) + fitmeasures <- values$Fit_Measures$text + text <- paste0("A Bayesian model was fitted (", + computations, + "). The fit indices are as following: ", + fitmeasures) # Summary # ------------- - summary <- .summary_lavaan(fit) + summary <- .summary_blavaan(fit, CI=CI, standardize=standardize) # Plot # ------------- - plot <- "Use `plot_lavaan` in association with ggraph." + plot <- "Use `get_graph` in association with ggraph." output <- list(text = values$Fit_Measures$text, plot = plot, summary = summary, values = values) @@ -62,41 +72,12 @@ analyze.lavaan <- function(x, ...) { #' @keywords internal -.interpret_fitmeasures.blavaan <- function(fit, indices=c("BIC", "DIC", "WAIC", "LOOIC")){ - values <- list() - - indices <- fitmeasures(fit) - - - for (index in names(indices)) { - values[index] <- indices[index] - } - - # Summary - summary <- as.data.frame(indices) %>% - rownames_to_column("Index") %>% - rename_("Value" = "indices") %>% - mutate_("Index" = "str_to_upper(Index)") - - # Text - relevant_indices <- summary[summary$Index %in% c("BIC", "DIC", "WAIC", "LOOIC"),] - text <- paste0(relevant_indices$Index, " = ", format_digit(relevant_indices$Value), collapse=", ") - - output <- list(text = text, summary = summary, values = values, plot="Not available yet") - class(output) <- c("psychobject", "list") - return(output) - -} - - - -#' @keywords internal -.get_info_computations.blavaan <- function(fit) { - chains <- blavInspect(fit, "n.chains") +.get_info_computations <- function(fit) { + chains <- blavaan::blavInspect(fit, "n.chains") sample = fit@external$sample warmup = fit@external$burnin text = paste0(chains, - "chains, each with iter = ", + " chains, each with iter = ", sample, "; warmup = ", warmup) @@ -107,7 +88,7 @@ analyze.lavaan <- function(x, ...) { #' @keywords internal -.process_blavaan <- function(fit, CI=90){ +.process_blavaan <- function(fit, standardize=FALSE, CI=90){ # Get relevant rows PE <- parameterEstimates(fit, se = FALSE, ci=FALSE, remove.eq = FALSE, remove.system.eq = TRUE, remove.ineq = FALSE, remove.def = FALSE, @@ -123,11 +104,20 @@ analyze.lavaan <- function(x, ...) { priors[relevant_rows] <- newpt$prior[pte2] priors[is.na(PE$prior)] <- "" + + + # Posterior - posteriors <- blavInspect(fit, "draws") %>% - as.matrix() %>% - as.data.frame() - names(posteriors) <- names(coef(fit)) + if(standardize == FALSE){ + posteriors <- blavaan::blavInspect(fit, "draws") %>% + as.matrix() %>% + as.data.frame() + names(posteriors) <- names(lavaan::coef(fit)) + } else{ + posteriors <- blavaan::standardizedposterior(fit) %>% + as.data.frame() + } + # Effects @@ -150,18 +140,27 @@ analyze.lavaan <- function(x, ...) { } - Effects <- rep(NA, nrow(PE)) - Effects[relevant_rows] <- Effect - MPEs <- rep(NA, nrow(PE)) - MPEs[relevant_rows] <- MPE - Medians <- rep(NA, nrow(PE)) - Medians[relevant_rows] <- Median - MADs <- rep(NA, nrow(PE)) - MADs[relevant_rows] <- MAD - CI_lowers <- rep(NA, nrow(PE)) - CI_lowers[relevant_rows] <- CI_lower - CI_highers <- rep(NA, nrow(PE)) - CI_highers[relevant_rows] <- CI_higher + if(standardize == FALSE){ + Effects <- rep(NA, nrow(PE)) + Effects[relevant_rows] <- Effect + MPEs <- rep(NA, nrow(PE)) + MPEs[relevant_rows] <- MPE + Medians <- rep(NA, nrow(PE)) + Medians[relevant_rows] <- Median + MADs <- rep(NA, nrow(PE)) + MADs[relevant_rows] <- MAD + CI_lowers <- rep(NA, nrow(PE)) + CI_lowers[relevant_rows] <- CI_lower + CI_highers <- rep(NA, nrow(PE)) + CI_highers[relevant_rows] <- CI_higher + } else{ + Effects <- Effect + MPEs <- MPE + Medians <- Median + MADs <- MAD + CI_lowers <- CI_lower + CI_highers <- CI_higher + } data <- data.frame("Effect" = Effects, "Median" = Medians, @@ -177,17 +176,15 @@ analyze.lavaan <- function(x, ...) { #' @keywords internal -.summary_lavaan <- function(fit){ - - solution <- parameterEstimates(fit, se = TRUE, ci=TRUE, standardized=TRUE) +.summary_blavaan <- function(fit, CI=90, standardize=FALSE){ + solution <- lavaan::parameterEstimates(fit, se = TRUE, ci=TRUE, standardized=FALSE, level = CI/100) solution <- solution %>% rename("From" = "rhs", "To" = "lhs", "Operator" = "op", "Coef" = "est", - "Coef_std" = "std.all", "SE" = "se", "CI_lower" = "ci.lower", "CI_higher" = "ci.upper") %>% @@ -196,89 +193,17 @@ analyze.lavaan <- function(x, ...) { Operator == "~" ~ "Regression", Operator == "~~" ~ "Correlation", TRUE ~ NA_character_)) %>% - select(one_of(c("To", "Operator", "From", "Coef_std", "Type"))) %>% - cbind(.process_blavaan(fit)) %>% + select(one_of(c("To", "Operator", "From", "Type"))) %>% + mutate_("Effect" = "as.character(paste0(To, Operator, From))") %>% + full_join(.process_blavaan(fit, CI=CI, standardize=standardize) %>% + mutate_("Effect" = "as.character(Effect)"), by="Effect") %>% select_("-Effect") %>% mutate_("Median" = "replace_na(Median, 1)", "MAD" = "replace_na(MAD, 0)", "MPE" = "replace_na(MPE, 100)") %>% - select(one_of(c("To", "Operator", "From", "Median", "MAD", "CI_lower", "CI_higher", "MPE", "Coef_std", "Prior", "Type"))) + select(one_of(c("From", "Operator", "To", "Median", "MAD", "CI_lower", "CI_higher", "MPE", "Prior", "Type"))) %>% + dplyr::filter_("Operator != '~1'") return(solution) } - - - - - - - -#' Plot lavaan (SEM or CFA) objects. -#' -#' Plot lavaan (SEM or CFA) objects. -#' -#' @param fit lavaan object. -#' @param links Which links to include? A list including at least one of "Regression", "Loading" or "Correlation". -#' @param threshold_p Omit all links with a p value below this value. -#' @param threshold_Coef Omit all links with a Coefs below this value. -#' @param digits Edges' labels rounding. -#' -#' @return A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. -#' -#' -#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} -#' -#' @seealso -#' https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM -#' -#' -#' @export -plot_lavaan <- function(fit, links=c("Regression"), threshold_p=NULL, threshold_Coef=NULL, digits=2){ -# https://www.r-bloggers.com/ggplot2-sem-models-with-tidygraph-and-ggraph/ - - summary <- summary(analyze(fit)) - - # Sanitize - if(is.null(threshold_p)){ - threshold_p <- 1.1 - } - if(is.null(threshold_Coef)){ - threshold_Coef <- max(abs(summary$Coef)) - } - - # Edge properties - edges <- summary %>% - filter_('Type %in% c(links)', - "From != To", - "p < threshold_p", - "abs(Coef) > threshold_Coef") %>% - rename_("to" = "To", - "from" = "From") %>% - mutate_('Label_Regression' = "ifelse(Type=='Regression', format_digit(Coef, digits), '')", - 'Label_Correlation' = "ifelse(Type=='Correlation', format_digit(Coef, digits), '')", - 'Label_Loading' = "ifelse(Type=='Loading', format_digit(Coef, digits), '')") - edges <- edges[colSums(!is.na(edges)) > 0] - - # Identify latent variables for nodes - latent_nodes <- edges %>% - filter_('Type == "Loading"') %>% - distinct_("to") %>% - transmute_("metric" = "to", "latent" = TRUE) - - nodes_list <- unique(c(edges$from, edges$to)) - - # Node properties - nodes <- summary %>% - filter_("From == To", - "From %in% nodes_list") %>% - mutate_("metric" = "From") %>% - left_join(latent_nodes, by="metric") %>% - mutate_("latent" = "if_else(is.na(latent), FALSE, latent)") - - return(output = list(nodes = nodes, edges = edges)) -} - - - - diff --git a/R/analyze.lavaan.R b/R/analyze.lavaan.R index 70c8871..8b5e635 100644 --- a/R/analyze.lavaan.R +++ b/R/analyze.lavaan.R @@ -1,8 +1,10 @@ -#' Analyze lavaan (SEM or CFA) objects. +#' Analyze lavaan SEM or CFA) objects. #' #' Analyze lavaan (SEM or CFA) objects. #' #' @param x lavaan object. +#' @param CI Confidence interval level. +#' @param standardize Compute standardized coefs. #' @param ... Arguments passed to or from other methods. #' #' @return output @@ -29,26 +31,28 @@ #' @importFrom lavaan parameterEstimates fitmeasures #' #' @export -analyze.lavaan <- function(x, ...) { +analyze.lavaan <- function(x, CI=95, standardize=FALSE, ...) { fit <- x # Processing # ------------- values <- list() + values$CI = CI # Fit measures - values$Fit_Measures <- .interpret_fitmeasures(fit) + values$Fit_Measures <- interpret_lavaan(fit) + # Summary # ------------- - summary <- .summary_lavaan(fit) + summary <- .summary_lavaan(fit, CI=CI, standardize=standardize) # Plot # ------------- - plot <- "Use `plot_lavaan` in association with ggraph." + plot <- "Use `get_graph` in association with ggraph." output <- list(text = values$Fit_Measures$text, plot = plot, summary = summary, values = values) @@ -61,92 +65,6 @@ analyze.lavaan <- function(x, ...) { -#' @keywords internal -.interpret_fitmeasures.lavaan <- function(fit){ - values <- list() - - indices <- lavaan::fitmeasures(fit) - - - for (index in names(indices)) { - values[index] <- indices[index] - } - - # awang2012 - # https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM - if (values$cfi >= 0.9) { - cfi <- "satisfactory" - } else { - cfi <- "poor" - } - if (values$rmsea <= 0.08) { - rmsea <- "satisfactory" - } else { - rmsea <- "poor" - } - if (values$gfi >= 0.9) { - gfi <- "satisfactory" - } else { - gfi <- "poor" - } - if (values$tli >= 0.9) { - tli <- "satisfactory" - } else { - tli <- "poor" - } - if (values$nfi >= 0.9) { - nfi <- "satisfactory" - } else { - nfi <- "poor" - } - - # Summary - summary <- data.frame( - Index = c("RMSEA", "CFI", "GFI", "TLI", "NFI", "Chisq"), - Value = c(values$rmsea, values$cfi, values$gfi, values$tli, values$nfi, values$chisq), - Interpretation = c(rmsea, cfi, gfi, tli, nfi, NA), - Treshold = c("< .08", "> .90", "> 0.90", "> 0.90", "> 0.90", NA) - ) - - # Text - if ("satisfactory" %in% summary$Interpretation) { - satisfactory <- summary %>% - filter_("Interpretation == 'satisfactory'") %>% - mutate_("Index" = "paste0(Index, ' (', format_digit(Value), ' ', Treshold, ')')") %>% - select_("Index") %>% - pull() %>% - paste0(collapse = ", ") - satisfactory <- paste0("The ", satisfactory, " show satisfactory indices of fit.") - } else { - satisfactory <- "" - } - if ("poor" %in% summary$Interpretation) { - poor <- summary %>% - filter_("Interpretation == 'poor'") %>% - mutate_( - "Treshold" = 'stringr::str_replace(Treshold, "<", "SUP")', - "Treshold" = 'stringr::str_replace(Treshold, ">", "INF")', - "Treshold" = 'stringr::str_replace(Treshold, "SUP", ">")', - "Treshold" = 'stringr::str_replace(Treshold, "INF", "<")' - ) %>% - mutate_("Index" = "paste0(Index, ' (', format_digit(Value), ' ', Treshold, ')')") %>% - select_("Index") %>% - pull() %>% - paste0(collapse = ", ") - poor <- paste0("The ", poor, " show poor indices of fit.") - } else { - poor <- "" - } - text <- paste(satisfactory, poor) - - output <- list(text = text, summary = summary, values = values, plot="Not available yet") - class(output) <- c("psychobject", "list") - return(output) - -} - - - @@ -156,16 +74,20 @@ analyze.lavaan <- function(x, ...) { #' @keywords internal -.summary_lavaan.lavaan <- function(fit){ +.summary_lavaan <- function(fit, CI=95, standardize=FALSE){ - solution <- lavaan::parameterEstimates(fit, standardized=TRUE) + if(standardize == FALSE){ + solution <- lavaan::parameterEstimates(fit, se=TRUE, standardized=standardize, level = CI/100) + }else{ + solution <- lavaan::standardizedsolution(fit, se=TRUE, level = CI/100) %>% + rename_("est" = "est.std") + } solution <- solution %>% rename("From" = "rhs", "To" = "lhs", "Operator" = "op", "Coef" = "est", - "Coef_std" = "std.all", "SE" = "se", "p" = "pvalue", "CI_lower" = "ci.lower", @@ -176,7 +98,7 @@ analyze.lavaan <- function(x, ...) { Operator == "~~" ~ "Correlation", TRUE ~ NA_character_)) %>% mutate_("p" = "replace_na(p, 0)") %>% - select(one_of(c("To", "Operator", "From", "Coef", "SE", "CI_lower", "CI_higher", "p", "Coef_std", "Type"))) + select(one_of(c("From", "Operator", "To", "Coef", "SE", "CI_lower", "CI_higher", "p", "Type"))) return(solution) } @@ -187,71 +109,3 @@ analyze.lavaan <- function(x, ...) { -#' Plot lavaan (SEM or CFA) objects. -#' -#' Plot lavaan (SEM or CFA) objects. -#' -#' @param fit lavaan object. -#' @param links Which links to include? A list including at least one of "Regression", "Loading" or "Correlation". -#' @param threshold_p Omit all links with a p value below this value. -#' @param threshold_Coef Omit all links with a Coefs below this value. -#' @param digits Edges' labels rounding. -#' -#' @return A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. -#' -#' -#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} -#' -#' @seealso -#' https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM -#' -#' -#' @export -plot_lavaan.lavaan <- function(fit, links=c("Regression"), threshold_p=NULL, threshold_Coef=NULL, digits=2){ -# https://www.r-bloggers.com/ggplot2-sem-models-with-tidygraph-and-ggraph/ - - summary <- summary(analyze(fit)) - - # Sanitize - if(is.null(threshold_p)){ - threshold_p <- 1.1 - } - if(is.null(threshold_Coef)){ - threshold_Coef <- max(abs(summary$Coef)) - } - - # Edge properties - edges <- summary %>% - filter_('Type %in% c(links)', - "From != To", - "p < threshold_p", - "abs(Coef) > threshold_Coef") %>% - rename_("to" = "To", - "from" = "From") %>% - mutate_('Label_Regression' = "ifelse(Type=='Regression', format_digit(Coef, digits), '')", - 'Label_Correlation' = "ifelse(Type=='Correlation', format_digit(Coef, digits), '')", - 'Label_Loading' = "ifelse(Type=='Loading', format_digit(Coef, digits), '')") - edges <- edges[colSums(!is.na(edges)) > 0] - - # Identify latent variables for nodes - latent_nodes <- edges %>% - filter_('Type == "Loading"') %>% - distinct_("to") %>% - transmute_("metric" = "to", "latent" = TRUE) - - nodes_list <- unique(c(edges$from, edges$to)) - - # Node properties - nodes <- summary %>% - filter_("From == To", - "From %in% nodes_list") %>% - mutate_("metric" = "From") %>% - left_join(latent_nodes, by="metric") %>% - mutate_("latent" = "if_else(is.na(latent), FALSE, latent)") - - return(output = list(nodes = nodes, edges = edges)) -} - - - - diff --git a/R/analyze.stanreg.R b/R/analyze.stanreg.R index 1cb2a97..b6c0743 100644 --- a/R/analyze.stanreg.R +++ b/R/analyze.stanreg.R @@ -35,7 +35,7 @@ #' plot(results) #' #' -#' fit <- rstanarm::stan_glmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) +#' fit <- rstanarm::stan_lmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) #' results <- analyze(fit) #' summary(results) #' @@ -344,7 +344,7 @@ analyze.stanreg <- function(x, CI = 90, index = "overlap", ROPE_bounds = NULL, e #' @keywords internal -.get_info_priors.stanreg <- function(varname, info_priors, predictors = NULL) { +.get_info_priors <- function(varname, info_priors, predictors = NULL) { # Prior # TBD: this doesn't work with categorical predictors :( values <- list() diff --git a/R/get_R2.R b/R/get_R2.R index 405aaf7..bb0b8e2 100644 --- a/R/get_R2.R +++ b/R/get_R2.R @@ -244,6 +244,10 @@ R2_LOO_Adjusted <- function(fit) { psis_object <- loo::psis(log_ratios = -ll, r_eff = r_eff) ypredloo <- loo::E_loo(ypred, psis_object, log_ratios = -ll)$value + if(length(ypredloo) != length(y)){ + warning("Something went wrong in the Loo-adjusted R2 computation.") + return(NA) + } eloo <- ypredloo - y adj_r_squared <- 1 - stats::var(eloo) / stats::var(y) @@ -253,9 +257,6 @@ R2_LOO_Adjusted <- function(fit) { - - - #' Tjur's (2009) coefficient of determination. #' #' Computes Tjur's (2009) coefficient of determination. diff --git a/R/get_graph.R b/R/get_graph.R new file mode 100644 index 0000000..8e5fe7c --- /dev/null +++ b/R/get_graph.R @@ -0,0 +1,187 @@ +#' Get graph data. +#' +#' To be used with tidygraph::tbl_graph. See the documentation for your object's class: +#' \itemize{ +#' \item{\link[=get_graph.lavaan]{get_graph.lavaan}} +#' \item{\link[=get_graph.fa]{get_graph.fa}} +#' } +#' +#' @param fit Object from which to extract the graph data. +#' @param ... Arguments passed to or from other methods. +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @export +get_graph <- function(fit, ...) { + UseMethod("get_graph") +} + + + + + + + + + + + + + + + + + + +#' Get graph data from lavaan or blavaan objects. +#' +#' Get graph data from lavaan or blavaan objects. +#' +#' @param fit lavaan object. +#' @param links Which links to include? A list including at least one of "Regression", "Loading" or "Correlation". +#' @param standardize Use standardized coefs. +#' @param threshold_Coef Omit all links with a Coefs below this value. +#' @param threshold_p Omit all links with a p value above this value. +#' @param threshold_MPE In case of a blavaan model, omit all links with a MPE value below this value. +#' @param digits Edges' labels rounding. +#' @param CI CI level. +#' @param labels_CI Add the CI in the edge label. +#' @param ... Arguments passed to or from other methods. +#' +#' @return A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' +#' @export +get_graph.lavaan <- function(fit, links=c("Regression", "Correlation", "Loading"), standardize=FALSE, threshold_Coef=NULL, threshold_p=NULL, threshold_MPE=NULL, digits=2, CI="default", labels_CI=TRUE, ...){ + # https://www.r-bloggers.com/ggplot2-sem-models-with-tidygraph-and-ggraph/ + + + if(labels_CI==TRUE){ + if(CI != "default"){ + results <- analyze(fit, CI=CI, standardize=standardize) + } else{ + results <- analyze(fit, standardize=standardize) + } + } else{ + results <- analyze(fit, standardize=standardize) + } + + summary <- summary(results) + CI <- results$values$CI + + # Check what type of model + if(class(fit) %in% c("blavaan")){ + summary$Coef <- summary$Median + if(is.null(threshold_MPE)){ + threshold_MPE <- -1 + } + summary <- summary %>% + filter_("MPE >= threshold_MPE") + + } else if(class(fit) %in% c("lavaan")){ + if(is.null(threshold_p)){ + threshold_p <- 1.1 + } + summary <- summary %>% + filter_("p <= threshold_p") + } else{ + stop(paste("Error in UseMethod('plot_lavaan') : no applicable method for 'plot_lavaan' applied to an object of class", class(fit))) + } + + # Deal with thresholds + if(is.null(threshold_Coef)){ + threshold_Coef <- min(abs(summary$Coef))-1 + } + + # Edge properties + edges <- summary %>% + mutate_("abs_coef" = "abs(Coef)") %>% + filter_('Type %in% c(links)', + "From != To", + "abs_coef >= threshold_Coef") %>% + select(-one_of("abs_coef")) %>% + rename_("to" = "To", + "from" = "From") + + # Labels + if(labels_CI == TRUE){ + edges <- edges %>% + mutate_('Label' = 'paste0(format_digit(Coef, digits), + ", ", CI, "% CI [", format_digit(CI_lower, digits), + ", ", format_digit(CI_higher, digits), "]")') + } else{ + edges <- edges %>% + mutate_('Label' = 'format_digit(Coef, digits)') + } + edges <- edges %>% + mutate_('Label_Regression' = "ifelse(Type=='Regression', Label, '')", + 'Label_Correlation' = "ifelse(Type=='Correlation', Label, '')", + 'Label_Loading' = "ifelse(Type=='Loading', Label, '')") + edges <- edges[colSums(!is.na(edges)) > 0] + + # Identify latent variables for nodes + latent_nodes <- edges %>% + filter_('Type == "Loading"') %>% + distinct_("to") %>% + transmute_("Name" = "to", "Latent" = TRUE) + + nodes_list <- unique(c(edges$from, edges$to)) + + # Node properties + nodes <- summary %>% + filter_("From == To", + "From %in% nodes_list") %>% + mutate_("Name" = "From") %>% + left_join(latent_nodes, by="Name") %>% + mutate_("Latent" = "if_else(is.na(Latent), FALSE, Latent)") %>% + select(one_of(c("Name", "Latent"))) + + return(list(nodes = nodes, edges = edges)) +} + + + + + +#' Get graph data from factor analysis. +#' +#' Get graph data from fa objects. +#' +#' @param fit psych::fa object. +#' @param threshold_Coef Omit all links with a Coefs below this value. +#' @param digits Edges' labels rounding. +#' @param ... Arguments passed to or from other methods. +#' +#' @return A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' +#' @export +#' @export +get_graph.fa <- function(fit, threshold_Coef=NULL, digits=2, ...){ + edges <- summary(analyze(fit)) %>% + gather("To", "Coef", -one_of("N", "Item", "Label")) %>% + rename_("From" = "Item") %>% + mutate_("Label" = "format_digit(Coef, digits)") %>% + select(one_of("From", "To", "Coef", "Label"), everything()) %>% + filter() + + # Deal with thresholds + if(is.null(threshold_Coef)){ + threshold_Coef <- min(abs(edges$Coef))-1 + } + + edges <- edges %>% + filter_("Coef > threshold_Coef") + + nodes <- data.frame("Name" = c(edges$From, edges$To)) %>% + distinct_("Name") + + return(list(nodes = nodes, edges = edges)) + +} diff --git a/R/interpret_lavaan.R b/R/interpret_lavaan.R new file mode 100644 index 0000000..0f061b3 --- /dev/null +++ b/R/interpret_lavaan.R @@ -0,0 +1,133 @@ +#' Interpret fit measures of lavaan or blavaan objects +#' @param fit lavaan or blavaan object. +#' @param ... Arguments passed to or from other methods. +#' @export +interpret_lavaan <- function(fit, ...) { + UseMethod("interpret_lavaan") +} + + + + + + + +#' @export +interpret_lavaan.lavaan <- function(fit, ...){ + values <- list() + + indices <- lavaan::fitmeasures(fit) + + + for (index in names(indices)) { + values[index] <- indices[index] + } + + # awang2012 + # https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM + if (values$cfi >= 0.9) { + cfi <- "satisfactory" + } else { + cfi <- "poor" + } + if (values$rmsea <= 0.08) { + rmsea <- "satisfactory" + } else { + rmsea <- "poor" + } + if (values$gfi >= 0.9) { + gfi <- "satisfactory" + } else { + gfi <- "poor" + } + if (values$tli >= 0.9) { + tli <- "satisfactory" + } else { + tli <- "poor" + } + if (values$nfi >= 0.9) { + nfi <- "satisfactory" + } else { + nfi <- "poor" + } + + # Summary + summary <- data.frame( + Index = c("RMSEA", "CFI", "GFI", "TLI", "NFI", "Chisq"), + Value = c(values$rmsea, values$cfi, values$gfi, values$tli, values$nfi, values$chisq), + Interpretation = c(rmsea, cfi, gfi, tli, nfi, NA), + Treshold = c("< .08", "> .90", "> 0.90", "> 0.90", "> 0.90", NA) + ) + + # Text + if ("satisfactory" %in% summary$Interpretation) { + satisfactory <- summary %>% + filter_("Interpretation == 'satisfactory'") %>% + mutate_("Index" = "paste0(Index, ' (', format_digit(Value), ' ', Treshold, ')')") %>% + select_("Index") %>% + pull() %>% + paste0(collapse = ", ") + satisfactory <- paste0("The ", satisfactory, " show satisfactory indices of fit.") + } else { + satisfactory <- "" + } + if ("poor" %in% summary$Interpretation) { + poor <- summary %>% + filter_("Interpretation == 'poor'") %>% + mutate_( + "Treshold" = 'stringr::str_replace(Treshold, "<", "SUP")', + "Treshold" = 'stringr::str_replace(Treshold, ">", "INF")', + "Treshold" = 'stringr::str_replace(Treshold, "SUP", ">")', + "Treshold" = 'stringr::str_replace(Treshold, "INF", "<")' + ) %>% + mutate_("Index" = "paste0(Index, ' (', format_digit(Value), ' ', Treshold, ')')") %>% + select_("Index") %>% + pull() %>% + paste0(collapse = ", ") + poor <- paste0("The ", poor, " show poor indices of fit.") + } else { + poor <- "" + } + text <- paste(satisfactory, poor) + + output <- list(text = text, summary = summary, values = values, plot="Not available yet") + class(output) <- c("psychobject", "list") + return(output) + +} + + + + + + +#' @param indices Vector of strings indicating which indices to report. Only works for bayesian objects for now. +#' @inheritParams interpret_lavaan +#' @export +interpret_lavaan.blavaan <- function(fit, indices=c("BIC", "DIC", "WAIC", "LOOIC"), ...){ + values <- list() + + indices <- lavaan::fitmeasures(fit) + + + for (index in names(indices)) { + values[index] <- indices[index] + } + + # Summary + summary <- as.data.frame(indices) %>% + rownames_to_column("Index") %>% + rename_("Value" = "indices") %>% + mutate_("Index" = "str_to_upper(Index)") + + # Text + relevant_indices <- summary[summary$Index %in% c("BIC", "DIC", "WAIC", "LOOIC"),] + text <- paste0(relevant_indices$Index, " = ", format_digit(relevant_indices$Value), collapse=", ") + + output <- list(text = text, summary = summary, values = values, plot="Not available yet") + class(output) <- c("psychobject", "list") + return(output) + +} + + diff --git a/man/analyze.Rd b/man/analyze.Rd index 20bed1f..67c37b9 100644 --- a/man/analyze.Rd +++ b/man/analyze.Rd @@ -26,7 +26,8 @@ Analyze objects. See the documentation for your object's class: } \itemize{ \item{\link[=analyze.fa]{analyze.fa}} - \item{\link[=analyze.fa]{analyze.lavaan}} + \item{\link[=analyze.lavaan]{analyze.lavaan}} + \item{\link[=analyze.blavaan]{analyze.blavaan}} } } \author{ diff --git a/man/analyze.blavaan.Rd b/man/analyze.blavaan.Rd new file mode 100644 index 0000000..ecb3e32 --- /dev/null +++ b/man/analyze.blavaan.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/analyze.blavaan.R +\name{analyze.blavaan} +\alias{analyze.blavaan} +\title{Analyze blavaan (SEM or CFA) objects.} +\usage{ +\method{analyze}{blavaan}(x, CI = 90, standardize = FALSE, ...) +} +\arguments{ +\item{x}{lavaan object.} + +\item{CI}{Credible interval level.} + +\item{standardize}{Compute standardized coefs.} + +\item{...}{Arguments passed to or from other methods.} +} +\value{ +output +} +\description{ +Analyze blavaan (SEM or CFA) objects. +} +\examples{ +library(psycho) +library(lavaan) + +model <- ' visual =~ x1 + x2 + x3 + textual =~ x4 + x5 + x6 + speed =~ x7 + x8 + x9 ' +x <- lavaan::cfa(model, data=HolzingerSwineford1939) + +rez <- analyze(x) +print(rez) + + +} +\seealso{ +https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/analyze.lavaan.Rd b/man/analyze.lavaan.Rd index 4fec644..387e00a 100644 --- a/man/analyze.lavaan.Rd +++ b/man/analyze.lavaan.Rd @@ -2,13 +2,17 @@ % Please edit documentation in R/analyze.lavaan.R \name{analyze.lavaan} \alias{analyze.lavaan} -\title{Analyze lavaan (SEM or CFA) objects.} +\title{Analyze lavaan SEM or CFA) objects.} \usage{ -\method{analyze}{lavaan}(x, ...) +\method{analyze}{lavaan}(x, CI = 95, standardize = FALSE, ...) } \arguments{ \item{x}{lavaan object.} +\item{CI}{Confidence interval level.} + +\item{standardize}{Compute standardized coefs.} + \item{...}{Arguments passed to or from other methods.} } \value{ diff --git a/man/analyze.stanreg.Rd b/man/analyze.stanreg.Rd index 3214a5e..f917a79 100644 --- a/man/analyze.stanreg.Rd +++ b/man/analyze.stanreg.Rd @@ -52,7 +52,7 @@ print(results) plot(results) -fit <- rstanarm::stan_glmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) +fit <- rstanarm::stan_lmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) results <- analyze(fit) summary(results) diff --git a/man/get_graph.Rd b/man/get_graph.Rd new file mode 100644 index 0000000..a49620e --- /dev/null +++ b/man/get_graph.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_graph.R +\name{get_graph} +\alias{get_graph} +\title{Get graph data.} +\usage{ +get_graph(fit, ...) +} +\arguments{ +\item{fit}{Object from which to extract the graph data.} + +\item{...}{Arguments passed to or from other methods.} +} +\description{ +To be used with tidygraph::tbl_graph. See the documentation for your object's class: +\itemize{ + \item{\link[=get_graph.lavaan]{get_graph.lavaan}} + \item{\link[=get_graph.fa]{get_graph.fa}} + } +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/get_graph.fa.Rd b/man/get_graph.fa.Rd new file mode 100644 index 0000000..ccd7b18 --- /dev/null +++ b/man/get_graph.fa.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_graph.R +\name{get_graph.fa} +\alias{get_graph.fa} +\title{Get graph data from factor analysis.} +\usage{ +\method{get_graph}{fa}(fit, threshold_Coef = NULL, digits = 2, ...) +} +\arguments{ +\item{fit}{psych::fa object.} + +\item{threshold_Coef}{Omit all links with a Coefs below this value.} + +\item{digits}{Edges' labels rounding.} + +\item{...}{Arguments passed to or from other methods.} +} +\value{ +A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. +} +\description{ +Get graph data from fa objects. +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/get_graph.lavaan.Rd b/man/get_graph.lavaan.Rd new file mode 100644 index 0000000..71ace85 --- /dev/null +++ b/man/get_graph.lavaan.Rd @@ -0,0 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_graph.R +\name{get_graph.lavaan} +\alias{get_graph.lavaan} +\title{Get graph data from lavaan or blavaan objects.} +\usage{ +\method{get_graph}{lavaan}(fit, links = c("Regression", "Correlation", + "Loading"), standardize = FALSE, threshold_Coef = NULL, + threshold_p = NULL, threshold_MPE = NULL, digits = 2, + CI = "default", labels_CI = TRUE, ...) +} +\arguments{ +\item{fit}{lavaan object.} + +\item{links}{Which links to include? A list including at least one of "Regression", "Loading" or "Correlation".} + +\item{standardize}{Use standardized coefs.} + +\item{threshold_Coef}{Omit all links with a Coefs below this value.} + +\item{threshold_p}{Omit all links with a p value above this value.} + +\item{threshold_MPE}{In case of a blavaan model, omit all links with a MPE value below this value.} + +\item{digits}{Edges' labels rounding.} + +\item{CI}{CI level.} + +\item{labels_CI}{Add the CI in the edge label.} + +\item{...}{Arguments passed to or from other methods.} +} +\value{ +A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. +} +\description{ +Get graph data from lavaan or blavaan objects. +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/interpret_lavaan.Rd b/man/interpret_lavaan.Rd new file mode 100644 index 0000000..2d94532 --- /dev/null +++ b/man/interpret_lavaan.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interpret_lavaan.R +\name{interpret_lavaan} +\alias{interpret_lavaan} +\title{Interpret fit measures of lavaan or blavaan objects} +\usage{ +interpret_lavaan(fit, ...) +} +\arguments{ +\item{fit}{lavaan or blavaan object.} + +\item{...}{Arguments passed to or from other methods.} +} +\description{ +Interpret fit measures of lavaan or blavaan objects +} diff --git a/man/plot_lavaan.Rd b/man/plot_lavaan.Rd deleted file mode 100644 index 78c4814..0000000 --- a/man/plot_lavaan.Rd +++ /dev/null @@ -1,30 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/analyze.lavaan.R -\name{plot_lavaan} -\alias{plot_lavaan} -\title{Plot lavaan (SEM or CFA) objects.} -\usage{ -plot_lavaan(fit, links = c("Regression"), threshold_p = NULL, - threshold_Coef = NULL) -} -\arguments{ -\item{fit}{lavaan object.} - -\item{links}{Which links to include? A list including at least one of "Regression", "Loading" or "Correlation".} - -\item{threshold_p}{Omit all links with a p value below this value.} - -\item{threshold_Coef}{Omit all links with a Coefs below this value.} -} -\value{ -A list containing nodes and edges data to be used by `tidygraph::tbl_graph()`. -} -\description{ -Plot lavaan (SEM or CFA) objects. -} -\seealso{ -https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM -} -\author{ -\href{https://dominiquemakowski.github.io/}{Dominique Makowski} -} From 23a5aa99fb7b8e6be6fb816172e954ced6ab835b Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Thu, 6 Dec 2018 12:34:26 +0100 Subject: [PATCH 14/17] added several utillity functions --- DESCRIPTION | 2 +- NAMESPACE | 5 ++++ R/analyze.R | 3 ++- R/analyze.fa.R | 5 ++++ R/analyze.principal.R | 45 +++++++++++++++++++++++++++++++ R/cite_packages.R | 40 +++++++++++++++++++++++++++ R/find_distance_cluster.R | 28 +++++++++++++++++++ R/find_highest_density_point.R | 18 +++++++++++++ R/interpret_lavaan.R | 6 +++++ R/remove_empty_cols.R | 2 +- R/remove_outliers.R | 43 +++++++++++++++++++++++++++++ inst/CITATION | 2 +- man/analyze.Rd | 3 ++- man/analyze.principal.Rd | 39 +++++++++++++++++++++++++++ man/cite_packages.Rd | 24 +++++++++++++++++ man/find_distance_cluster.Rd | 19 +++++++++++++ man/find_highest_density_point.Rd | 19 +++++++++++++ man/interpret_lavaan.Rd | 3 +++ man/remove_empty_cols.Rd | 2 +- man/remove_outliers.Rd | 24 +++++++++++++++++ 20 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 R/analyze.principal.R create mode 100644 R/cite_packages.R create mode 100644 R/find_distance_cluster.R create mode 100644 R/find_highest_density_point.R create mode 100644 R/remove_outliers.R create mode 100644 man/analyze.principal.Rd create mode 100644 man/cite_packages.Rd create mode 100644 man/find_distance_cluster.Rd create mode 100644 man/find_highest_density_point.Rd create mode 100644 man/remove_outliers.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 43601e2..97eb756 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -28,7 +28,7 @@ Description: The main goal of the psycho package is to provide tools for psychol License: MIT + file LICENSE Encoding: UTF-8 LazyData: true -RoxygenNote: 6.1.0 +RoxygenNote: 6.1.1 Depends: R (>= 3.5.0) Imports: diff --git a/NAMESPACE b/NAMESPACE index c3333f0..cf9f338 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -11,6 +11,7 @@ S3method(analyze,htest) S3method(analyze,lavaan) S3method(analyze,lm) S3method(analyze,lmerModLmerTest) +S3method(analyze,principal) S3method(analyze,stanreg) S3method(as.data.frame,density) S3method(find_best_model,lmerModLmerTest) @@ -77,6 +78,7 @@ export(analyze) export(assess) export(bayes_cor) export(bayes_cor.test) +export(cite_packages) export(correlation) export(crawford.test) export(crawford.test.freq) @@ -85,6 +87,8 @@ export(create_intervals) export(dprime) export(find_best_model) export(find_combinations) +export(find_distance_cluster) +export(find_highest_density_point) export(find_matching_string) export(find_random_effects) export(find_season) @@ -135,6 +139,7 @@ export(power_analysis) export(probs_to_odds) export(refdata) export(remove_empty_cols) +export(remove_outliers) export(reorder_matrix) export(rnorm_perfect) export(rope) diff --git a/R/analyze.R b/R/analyze.R index b64b8c2..d8e2032 100644 --- a/R/analyze.R +++ b/R/analyze.R @@ -6,7 +6,7 @@ #' \item{\link[=analyze.lmerModLmerTest]{analyze.merModLmerTest}} #' \item{\link[=analyze.glmerMod]{analyze.glmerMod}} #' \item{\link[=analyze.lm]{analyze.lm}} -#' \item{\link[=analyze.lm]{analyze.glm}} +#' \item{\link[=analyze.glm]{analyze.glm}} #' } #' \itemize{ #' \item{\link[=analyze.htest]{analyze.htest}} @@ -14,6 +14,7 @@ #' } #' \itemize{ #' \item{\link[=analyze.fa]{analyze.fa}} +#' \item{\link[=analyze.principal]{analyze.principal}} #' \item{\link[=analyze.lavaan]{analyze.lavaan}} #' \item{\link[=analyze.blavaan]{analyze.blavaan}} #' } diff --git a/R/analyze.fa.R b/R/analyze.fa.R index fe2f11f..0cffc48 100644 --- a/R/analyze.fa.R +++ b/R/analyze.fa.R @@ -265,3 +265,8 @@ plot_loadings <- function(loadings) { return(p) } + + + + + diff --git a/R/analyze.principal.R b/R/analyze.principal.R new file mode 100644 index 0000000..8cfa693 --- /dev/null +++ b/R/analyze.principal.R @@ -0,0 +1,45 @@ +#' Analyze fa objects. +#' +#' Analyze fa objects. +#' +#' @param x An psych object. +#' @param labels Supply a additional column with e.g. item labels. +#' @param treshold 'max' or numeric. The treshold over which to associate an item with its component. +#' @param ... Arguments passed to or from other methods. +#' +#' @return output +#' +#' @examples +#' library(psycho) +#' library(psych) +#' +#' x <- psych::pca(psych::Thurstone.33, 2) +#' +#' results <- analyze(x) +#' print(results) +#' summary(results) +#' plot(results) +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @export +analyze.principal <- function(x, labels = NULL, treshold = "max", ...) { + loadings <- format_loadings(x, labels) + + values <- list() + values$variance <- x$Vaccounted + values$loadings <- loadings$loadings + values$loadings_max <- loadings$max + values$cfa_model <- get_cfa_model(loadings$loadings, treshold = treshold) + + text <- .fa_variance_text(values$variance) + text <- paste0(text, "\n\n", format(values$cfa_model)) + summary <- values$loadings + plot <- plot_loadings(values$loadings) + + output <- list(text = text, plot = plot, summary = summary, values = values) + + class(output) <- c("psychobject", "list") + return(output) +} diff --git a/R/cite_packages.R b/R/cite_packages.R new file mode 100644 index 0000000..5cce8e3 --- /dev/null +++ b/R/cite_packages.R @@ -0,0 +1,40 @@ +#' Citations of loaded packages. +#' +#' Get the citations of loaded packages. +#' +#' @param session A `devtools::sessionInfo()` object. +#' +#' @examples +#' \dontrun{ +#' library(psycho) +#' cite_packages(sessionInfo()) +#' } +#' +#' @author \href{https://github.com/DominiqueMakowski}{Dominique Makowski} +#' +#' @export +cite_packages <- function(session){ + pkgs <- session$otherPkgs + citations <- c() + for(pkg_name in names(pkgs)){ + pkg <- pkgs[[pkg_name]] + + citation <- format(citation(pkg_name))[[2]] %>% + stringr::str_split("\n") %>% + flatten() %>% + paste(collapse="SPLIT") %>% + stringr::str_split("SPLITSPLIT") + + i = 1 + while(stringr::str_detect(citation[[1]][i], "To cite ")){i = i + 1} + + + citation <- citation[[1]][i] %>% + stringr::str_remove_all("SPLIT") %>% + stringr::str_trim() %>% + stringr::str_squish() + + citations <- c(citations, citation) + } + return(data.frame("Packages" = citations)) +} diff --git a/R/find_distance_cluster.R b/R/find_distance_cluster.R new file mode 100644 index 0000000..cfe4fdc --- /dev/null +++ b/R/find_distance_cluster.R @@ -0,0 +1,28 @@ +#' Find the distance of a point with its kmean cluster. +#' +#' Find the distance of a point with its kmean cluster. +#' +#' @param df Data +#' @param km kmean object. +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @export +find_distance_cluster <- function(df, km){ + + myDist <- function(p1, p2) sqrt((p1[,1]-p2[,1])^2+(p1[,2]-p2[,2])^2) + + data <- df %>% + as.data.frame() %>% + select(one_of(colnames(km$centers))) + + n_clusters <- nrow(km$centers) + + data$Distance <- NA + for(clust in 1:n_clusters){ + data$Distance[km$cluster==clust] <- myDist(data[km$cluster==clust,], km$centers[clust,,drop=FALSE]) + } + + return(data$Distance) +} diff --git a/R/find_highest_density_point.R b/R/find_highest_density_point.R new file mode 100644 index 0000000..52c8a28 --- /dev/null +++ b/R/find_highest_density_point.R @@ -0,0 +1,18 @@ +#' Find the Highest Density Point. +#' +#' Returns the Highest Density Point. +#' +#' @param x Vector. +#' @param precision Number of points in density. +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @export +find_highest_density_point <- function(x, precision=1e+03){ + d <- x %>% + density(n=precision) %>% + as.data.frame() + y <- d$x[which.max(d$y)] + return(y) +} diff --git a/R/interpret_lavaan.R b/R/interpret_lavaan.R index 0f061b3..b1893bd 100644 --- a/R/interpret_lavaan.R +++ b/R/interpret_lavaan.R @@ -1,6 +1,12 @@ #' Interpret fit measures of lavaan or blavaan objects +#' +#' Interpret fit measures of lavaan or blavaan objects +#' #' @param fit lavaan or blavaan object. #' @param ... Arguments passed to or from other methods. +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' #' @export interpret_lavaan <- function(fit, ...) { UseMethod("interpret_lavaan") diff --git a/R/remove_empty_cols.R b/R/remove_empty_cols.R index 0bbf90b..9590e4c 100644 --- a/R/remove_empty_cols.R +++ b/R/remove_empty_cols.R @@ -1,4 +1,4 @@ -#' Remove empty columns.. +#' Remove empty columns. #' #' Removes all columns containing ony NaNs. #' diff --git a/R/remove_outliers.R b/R/remove_outliers.R new file mode 100644 index 0000000..ffbc505 --- /dev/null +++ b/R/remove_outliers.R @@ -0,0 +1,43 @@ +#' Remove outliers. +#' +#' Removes outliers (with the z-score method only for now). +#' +#' @param df Dataframe. +#' @param target String or list of strings of variables +#' @param threshold The z-score value (deviation of SD) by which to consider outliers. +#' @param direction Can be "both", "upper" or "lower". +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @export +remove_outliers <- function(df, target, threshold=qnorm(0.95), direction="both"){ + for(var in c(target)){ + df <- .remove_outliers(df, var, threshold, direction) + } + return(df) +} + + + + + + +#' @keywords internal +.remove_outliers <- function(df, target, threshold=qnorm(0.95), direction="both"){ + df <- df %>% + mutate_("outlier_criterion" = target) %>% + standardize(subset="outlier_criterion") + if(direction %in% c("both", "upper")){ + df <- df %>% + filter_("outlier_criterion <= threshold") + } + if(direction %in% c("both", "lower")){ + df <- df %>% + filter_("outlier_criterion >= -threshold") + } + + df <- df %>% + select_("-outlier_criterion") + + return(df) +} diff --git a/inst/CITATION b/inst/CITATION index 1637364..a54d8d5 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -14,6 +14,6 @@ bibentry( textVersion = paste("Makowski, D. (2018). The Psycho Package: An Efficient and Publishing-Oriented Workflow for Psychological Science. Journal of Open Source Software, 3(22), 470.", "Available from https://github.com/neuropsychology/psycho.R", - sep=""), + sep=" "), mheader = "To cite psycho in publications use:") \ No newline at end of file diff --git a/man/analyze.Rd b/man/analyze.Rd index 67c37b9..422ecc6 100644 --- a/man/analyze.Rd +++ b/man/analyze.Rd @@ -18,7 +18,7 @@ Analyze objects. See the documentation for your object's class: \item{\link[=analyze.lmerModLmerTest]{analyze.merModLmerTest}} \item{\link[=analyze.glmerMod]{analyze.glmerMod}} \item{\link[=analyze.lm]{analyze.lm}} - \item{\link[=analyze.lm]{analyze.glm}} + \item{\link[=analyze.glm]{analyze.glm}} } \itemize{ \item{\link[=analyze.htest]{analyze.htest}} @@ -26,6 +26,7 @@ Analyze objects. See the documentation for your object's class: } \itemize{ \item{\link[=analyze.fa]{analyze.fa}} + \item{\link[=analyze.principal]{analyze.principal}} \item{\link[=analyze.lavaan]{analyze.lavaan}} \item{\link[=analyze.blavaan]{analyze.blavaan}} } diff --git a/man/analyze.principal.Rd b/man/analyze.principal.Rd new file mode 100644 index 0000000..cedf2b2 --- /dev/null +++ b/man/analyze.principal.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/analyze.principal.R +\name{analyze.principal} +\alias{analyze.principal} +\title{Analyze fa objects.} +\usage{ +\method{analyze}{principal}(x, labels = NULL, treshold = "max", ...) +} +\arguments{ +\item{x}{An psych object.} + +\item{labels}{Supply a additional column with e.g. item labels.} + +\item{treshold}{'max' or numeric. The treshold over which to associate an item with its component.} + +\item{...}{Arguments passed to or from other methods.} +} +\value{ +output +} +\description{ +Analyze fa objects. +} +\examples{ +library(psycho) +library(psych) + +x <- psych::pca(psych::Thurstone.33, 2) + +results <- analyze(x) +print(results) +summary(results) +plot(results) + + +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/cite_packages.Rd b/man/cite_packages.Rd new file mode 100644 index 0000000..3a1e85a --- /dev/null +++ b/man/cite_packages.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cite_packages.R +\name{cite_packages} +\alias{cite_packages} +\title{Citations of loaded packages.} +\usage{ +cite_packages(session) +} +\arguments{ +\item{session}{A `devtools::sessionInfo()` object.} +} +\description{ +Get the citations of loaded packages. +} +\examples{ +\dontrun{ +library(psycho) +cite_packages(sessionInfo()) +} + +} +\author{ +\href{https://github.com/DominiqueMakowski}{Dominique Makowski} +} diff --git a/man/find_distance_cluster.Rd b/man/find_distance_cluster.Rd new file mode 100644 index 0000000..3991d08 --- /dev/null +++ b/man/find_distance_cluster.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/find_distance_cluster.R +\name{find_distance_cluster} +\alias{find_distance_cluster} +\title{Find the distance of a point with its kmean cluster.} +\usage{ +find_distance_cluster(df, km) +} +\arguments{ +\item{df}{Data} + +\item{km}{kmean object.} +} +\description{ +Find the distance of a point with its kmean cluster. +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/find_highest_density_point.Rd b/man/find_highest_density_point.Rd new file mode 100644 index 0000000..1645db9 --- /dev/null +++ b/man/find_highest_density_point.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/find_highest_density_point.R +\name{find_highest_density_point} +\alias{find_highest_density_point} +\title{Find the Highest Density Point.} +\usage{ +find_highest_density_point(x, precision = 1000) +} +\arguments{ +\item{x}{Vector.} + +\item{precision}{Number of points in density.} +} +\description{ +Returns the Highest Density Point. +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/interpret_lavaan.Rd b/man/interpret_lavaan.Rd index 2d94532..a722050 100644 --- a/man/interpret_lavaan.Rd +++ b/man/interpret_lavaan.Rd @@ -14,3 +14,6 @@ interpret_lavaan(fit, ...) \description{ Interpret fit measures of lavaan or blavaan objects } +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/remove_empty_cols.Rd b/man/remove_empty_cols.Rd index a0e8bb2..870ecd3 100644 --- a/man/remove_empty_cols.Rd +++ b/man/remove_empty_cols.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/remove_empty_cols.R \name{remove_empty_cols} \alias{remove_empty_cols} -\title{Remove empty columns..} +\title{Remove empty columns.} \usage{ remove_empty_cols(df) } diff --git a/man/remove_outliers.Rd b/man/remove_outliers.Rd new file mode 100644 index 0000000..a10fd3c --- /dev/null +++ b/man/remove_outliers.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/remove_outliers.R +\name{remove_outliers} +\alias{remove_outliers} +\title{Remove outliers.} +\usage{ +remove_outliers(df, target, threshold = qnorm(0.95), + direction = "both") +} +\arguments{ +\item{df}{Dataframe.} + +\item{target}{String or list of strings of variables} + +\item{threshold}{The z-score value (deviation of SD) by which to consider outliers.} + +\item{direction}{Can be "both", "upper" or "lower".} +} +\description{ +Removes outliers (with the z-score method only for now). +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} From 9f8505aaa0e908aec1f3f6b75c278e527cd87588 Mon Sep 17 00:00:00 2001 From: Dominique Makowski Date: Thu, 13 Dec 2018 17:06:11 +0100 Subject: [PATCH 15/17] lavaan --- NAMESPACE | 1 + R/analyze.lavaan.R | 11 +- R/correlation.R | 2 +- R/find_best_model.lavaan.R | 162 +++++++++++++++++++++++ R/get_graph.R | 41 +++++- R/get_predicted.merMod.R | 15 ++- R/get_predicted.stanreg.R | 18 +-- R/interpret_lavaan.R | 4 +- R/refdata.R | 5 +- docs/~$index.html | Bin 0 -> 162 bytes man/get_graph.Rd | 1 + man/get_graph.psychobject_correlation.Rd | 22 +++ 12 files changed, 261 insertions(+), 21 deletions(-) create mode 100644 R/find_best_model.lavaan.R create mode 100644 docs/~$index.html create mode 100644 man/get_graph.psychobject_correlation.Rd diff --git a/NAMESPACE b/NAMESPACE index cf9f338..0f99a33 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -38,6 +38,7 @@ S3method(get_formula,lmerModLmerTest) S3method(get_formula,stanreg) S3method(get_graph,fa) S3method(get_graph,lavaan) +S3method(get_graph,psychobject_correlation) S3method(get_info,glm) S3method(get_info,glmerMod) S3method(get_info,lm) diff --git a/R/analyze.lavaan.R b/R/analyze.lavaan.R index 8b5e635..1816497 100644 --- a/R/analyze.lavaan.R +++ b/R/analyze.lavaan.R @@ -97,8 +97,15 @@ analyze.lavaan <- function(x, CI=95, standardize=FALSE, ...) { Operator == "~" ~ "Regression", Operator == "~~" ~ "Correlation", TRUE ~ NA_character_)) %>% - mutate_("p" = "replace_na(p, 0)") %>% - select(one_of(c("From", "Operator", "To", "Coef", "SE", "CI_lower", "CI_higher", "p", "Type"))) + mutate_("p" = "replace_na(p, 0)") + + if("group" %in% names(solution)){ + solution <- solution %>% + rename("Group" = "group") %>% + select(one_of(c("Group", "From", "Operator", "To", "Coef", "SE", "CI_lower", "CI_higher", "p", "Type"))) + } else{ + solution <- select(solution, one_of(c("From", "Operator", "To", "Coef", "SE", "CI_lower", "CI_higher", "p", "Type"))) + } return(solution) } diff --git a/R/correlation.R b/R/correlation.R index 546cd03..3a479ff 100644 --- a/R/correlation.R +++ b/R/correlation.R @@ -324,6 +324,6 @@ correlation <- function(df, # ------------- output <- list(text = text, plot = plot, summary = summary, values = values) - class(output) <- c("psychobject", "list") + class(output) <- c("psychobject", "psychobject_correlation", "list") return(output) } diff --git a/R/find_best_model.lavaan.R b/R/find_best_model.lavaan.R new file mode 100644 index 0000000..e4f9bc7 --- /dev/null +++ b/R/find_best_model.lavaan.R @@ -0,0 +1,162 @@ +#' Returns all combinations of lavaan models with their indices of fit. +#' +#' Returns all combinations of lavaan models with their indices of fit. +#' +#' @param fit A lavaan object. +#' @param samples Number of random draws. +#' @param verbose Show progress. +#' @param ... Arguments passed to or from other methods. +#' +#' @return list containing all combinations. +#' +#' @examples +#' library(psycho) +#' library(lavaan) +#' +#' model <- ' visual =~ x1 + x2 + x3 +#' textual =~ x4 + x5 + x6 +#' speed =~ x7 + x8 + x9 +#' visual ~ textual +#' textual ~ speed' +#' fit <- lavaan::sem(model, data=HolzingerSwineford1939) +#' +#' models <- find_best_model.lavaan(fit, latent="visual =~ x1 + x2 + x3 +#' textual =~ x4 + x5 + x6 +#' speed =~ x7 + x8 + x9") +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' @import dplyr +#' +#' @method find_best_model stanreg +#' @export +find_best_model.lavaan <- function(fit, latent="", samples=1000, verbose=FALSE, ...){ + + update_model <- function(fit, latent, model){ + newfit <- update(fit, paste0(latent, "\n", model)) + + indices <- data.frame(Value = fitMeasures(newfit)) %>% + tibble::rownames_to_column("Index") %>% + tidyr::spread_("Index", "Value") %>% + cbind(data.frame(model = model, + n_links = nrow(lavaan::lavInspect(fit, "est")$beta))) + return(indices) + } + + vars <- row.names(lavaan::lavInspect(fit, "est")$beta) + # info <- fit@Model + + data <- data.frame() + for(outcome in vars){ + remaning_vars <- vars[!stringr::str_detect(vars, outcome)] + combinations <- c() + for(y in 1:length(remaning_vars)){ + combinations <- c(combinations, combn(remaning_vars, y, simplify=FALSE)) + } + combinations <- sapply(combinations, paste0, collapse = "+") + combinations <- paste0(outcome, "~", combinations) + x <- data.frame(A = combinations) + names(x) <- c(outcome) + if(nrow(data) == 0){ + data <- x + } else{ + data <- cbind(data, x) + } + } + + data <- rbind(data, head(data[NA,], 1)) + data[] <- lapply(data, as.character) + data[is.na(data)] <- "" + rownames(data) <- NULL + + out <- data.frame() + for(i in 1:samples){ + if(verbose==TRUE){ + cat(".") + } + model <- "" + for(var in names(data)){ + model <- paste0(model, sample(data[[var]], 1), "\n") + } + + if(!model %in% out$model){ + out <- tryCatch( + rbind(out, update_model(fit, latent, model)), + error=function(e) out, + warning=function(w) out) + } + } + return(out) + } + + + + # vars <- row.names(lavaan::lavInspect(fit, "est")$lambda) + # + # possibilities <- list() + # for(var in vars){ + # remaning_vars <- paste(vars[!str_detect(vars, var)], collapse = "+") + # formula <- as.formula(paste(var, "~", remaning_vars)) + # combinations <- find_combinations(formula, interaction = FALSE) + # possibilities[[var]] <- combinations + # } + # + # + # + # get_solution <- function(possibilities, fit, out){ + # n <- sample(1:length(possibilities), 1) + # predictors <- sample(possibilities, n) + # model <- "" + # for(var in names(predictors)){ + # model <- paste0(model, sample(predictors[[var]], 1), "\n") + # if(model %in% out$model){ + # next + # } + # } + # newfit <- update(fit, model) + # indices <- data.frame(Value = fitMeasures(newfit)) %>% + # tibble::rownames_to_column("Index") %>% + # tidyr::spread_("Index", "Value") %>% + # cbind(data.frame(model = model, + # n_outcomes = n, + # n_links = nrow(lavaan::lavInspect(fit, "est")$beta))) + # out <- rbind(out, indices) + # return(out) + # } + # + # out <- data.frame() + # for(i in 1:samples){ + # if(verbose==TRUE){ + # print(paste0(round(i/samples*100), "%")) + # } + # out <- tryCatch( + # get_solution(possibilities, fit, out), + # error=function(e) out, + # warning=function(w) out) + # } + # + # out %>% + # distinct() %>% + # return() +} + + + + + + + +# models <- apply(data, 1, paste, collapse="\n") + + +# possible_outcomes <- c() +# for(i in 1:length(vars)){ +# possible_outcomes <- c(possible_outcomes, combn(vars, i, simplify=FALSE)) +# } +# +# for(i in possible_outcomes){ +# +# # combinations <- refdata(possibilities) +# +# } + diff --git a/R/get_graph.R b/R/get_graph.R index 8e5fe7c..9015579 100644 --- a/R/get_graph.R +++ b/R/get_graph.R @@ -4,6 +4,7 @@ #' \itemize{ #' \item{\link[=get_graph.lavaan]{get_graph.lavaan}} #' \item{\link[=get_graph.fa]{get_graph.fa}} +#' \item{\link[=get_graph.psychobject_correlation]{get_graph.psychobject_correlation}} #' } #' #' @param fit Object from which to extract the graph data. @@ -162,7 +163,6 @@ get_graph.lavaan <- function(fit, links=c("Regression", "Correlation", "Loading" #' #' #' @export -#' @export get_graph.fa <- function(fit, threshold_Coef=NULL, digits=2, ...){ edges <- summary(analyze(fit)) %>% gather("To", "Coef", -one_of("N", "Item", "Label")) %>% @@ -185,3 +185,42 @@ get_graph.fa <- function(fit, threshold_Coef=NULL, digits=2, ...){ return(list(nodes = nodes, edges = edges)) } + + + + +#' Get graph data from correlation. +#' +#' Get graph data from correlation. +#' +#' @param fit Object from psycho::correlation. +#' @param ... Arguments passed to or from other methods. +#' +#' @return A list containing nodes and edges data to be used by `igraph::graph_from_data_frame()`. +#' +#' +#' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} +#' +#' +#' @export +get_graph.psychobject_correlation <- function(fit, ...){ + + vars <- row.names(fit$values$r) + + r <- fit$values$r %>% + as.data.frame() %>% + tibble::rownames_to_column("from") %>% + tidyr::gather("to", "r", vars) + + if("p" %in% names(fit$values)){ + r <- r %>% + full_join( + fit$values$p %>% + as.data.frame() %>% + tibble::rownames_to_column("from") %>% + tidyr::gather("to", "p", vars), by = c("from", "to")) + } + + r <- filter(r, !from == to) + return(r) +} diff --git a/R/get_predicted.merMod.R b/R/get_predicted.merMod.R index 7223d0b..c62defe 100644 --- a/R/get_predicted.merMod.R +++ b/R/get_predicted.merMod.R @@ -88,18 +88,19 @@ get_predicted.merMod <- function(fit, newdata="model", prob=NULL, odds_to_probs= # Deal with random - if(re.form=="default"){ - # Check if all predictors are in variables - if(all(get_info(fit)$predictors %in% names(newdata))){ - re.form <- NULL - } else{ - re.form <- NA + if(!is.na(re.form)){ + if(re.form=="default"){ + # Check if all predictors are in variables + if(all(get_info(fit)$predictors %in% names(newdata))){ + re.form <- NULL + } else{ + re.form <- NA + } } } - # Compute ---------------------------------------------------------- pred_y <- as.data.frame(predict(fit, newdata = newdata, re.form = re.form)) diff --git a/R/get_predicted.stanreg.R b/R/get_predicted.stanreg.R index f40ff34..676e6b1 100644 --- a/R/get_predicted.stanreg.R +++ b/R/get_predicted.stanreg.R @@ -80,15 +80,17 @@ get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_pr } # Deal with potential random - if(re.form=="default"){ - if(is.mixed(fit)){ - # Check if all predictors are in variables - if(all(get_info(fit)$predictors %in% names(newdata))){ - re.form <- NULL - } else{ - re.form <- NA + if(!is.na(re.form)){ + if(re.form=="default"){ + if(is.mixed(fit)){ + # Check if all predictors are in variables + if(all(get_info(fit)$predictors %in% names(newdata))){ + re.form <- NULL + } else{ + re.form <- NA + } } - } + } } # Generate draws ------------------------------------------------------- diff --git a/R/interpret_lavaan.R b/R/interpret_lavaan.R index b1893bd..68f39f2 100644 --- a/R/interpret_lavaan.R +++ b/R/interpret_lavaan.R @@ -17,7 +17,9 @@ interpret_lavaan <- function(fit, ...) { - +#' Interpret fit measures of lavaan objects +#' +#' Interpret fit measures of lavaan objects #' @export interpret_lavaan.lavaan <- function(fit, ...){ values <- list() diff --git a/R/refdata.R b/R/refdata.R index 4f1b476..7872dd1 100644 --- a/R/refdata.R +++ b/R/refdata.R @@ -7,6 +7,7 @@ #' @param length.out Length of numeric target variables. #' @param factors Type of summary for factors. Can be "combination" or "reference". #' @param numerics Type of summary for numerics Can be "combination", any function ("mean", "median", ...) or a value. +#' @param na.rm Remove NaNs. #' #' @examples #' library(psycho) @@ -22,7 +23,7 @@ #' @importFrom purrr keep #' @import tidyr #' @export -refdata <- function(df, target = "all", length.out = 10, factors = "reference", numerics = "mean") { +refdata <- function(df, target = "all", length.out = 10, factors = "reference", numerics = "mean", na.rm=TRUE) { # Target if (all(target == "all") | ncol(df) == 1) { @@ -41,6 +42,8 @@ refdata <- function(df, target = "all", length.out = 10, factors = "reference", smart_summary <- function(x, numerics) { + if(na.rm == TRUE) x <- na.omit(x) + if (is.numeric(x)) { fun <- paste0(numerics, "(x)") out <- eval(parse(text = fun)) diff --git a/docs/~$index.html b/docs/~$index.html new file mode 100644 index 0000000000000000000000000000000000000000..dbf56053ba1df5f78a217c172771146e9a6dab72 GIT binary patch literal 162 zcmd;d@lDLmFE7r{WFP@>GPp4KG9)r&GvqUrGZX`9i1tepUf*G`Vd&V9bbgisBLf4B ph8cZj!pl1hwhSE?pz<&pCVy>$_#Fm2hAu9KD4@wD45 Date: Thu, 13 Dec 2018 18:43:43 +0100 Subject: [PATCH 16/17] hotfix --- R/find_best_model.lavaan.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/find_best_model.lavaan.R b/R/find_best_model.lavaan.R index e4f9bc7..e6d3b8d 100644 --- a/R/find_best_model.lavaan.R +++ b/R/find_best_model.lavaan.R @@ -138,7 +138,7 @@ find_best_model.lavaan <- function(fit, latent="", samples=1000, verbose=FALSE, # out %>% # distinct() %>% # return() -} +# } From 4f60a2bdc415ceeeae7bd52cbd6de999f974f990 Mon Sep 17 00:00:00 2001 From: DominiqueMakowski Date: Sun, 23 Dec 2018 14:53:42 +0100 Subject: [PATCH 17/17] fix n_factors and styler --- NAMESPACE | 1 + R/analyze.anova.R | 28 +++-- R/analyze.blavaan.R | 127 +++++++++++---------- R/analyze.fa.R | 34 ++---- R/analyze.glm.R | 5 +- R/analyze.glmerMod.R | 9 +- R/analyze.htest.R | 9 +- R/analyze.lavaan.R | 63 +++++------ R/analyze.lm.R | 7 +- R/analyze.lmerModLmerTest.R | 5 +- R/analyze.principal.R | 6 +- R/analyze.stanreg.R | 28 ++--- R/assess.R | 3 +- R/bayes_cor.R | 13 +-- R/cite_packages.R | 14 ++- R/correlation.R | 13 ++- R/crawford.test.R | 12 +- R/crawford_dissociation.test.R | 5 +- R/create_intervals.R | 18 ++- R/dprime.R | 32 +++--- R/find_best_model.lavaan.R | 134 ++++++----------------- R/find_best_model.lmerModLmerTest.R | 9 +- R/find_best_model.stanreg.R | 12 +- R/find_combinations.R | 8 +- R/find_distance_cluster.R | 9 +- R/find_highest_density_point.R | 4 +- R/find_matching_string.R | 1 - R/find_random_effects.R | 1 - R/find_season.R | 3 +- R/formatting.R | 10 +- R/get_R2.R | 30 ++--- R/get_contrasts.R | 23 ++-- R/get_data.R | 27 ++--- R/get_formula.R | 10 +- R/get_graph.R | 87 ++++++++------- R/get_info.R | 28 +++-- R/get_means.R | 19 ++-- R/get_predicted.glm.R | 22 ++-- R/get_predicted.lm.R | 23 ++-- R/get_predicted.merMod.R | 73 ++++++------ R/get_predicted.stanreg.R | 57 +++++----- R/golden.R | 3 +- R/hdi.R | 7 +- R/interpret_R2.R | 6 +- R/interpret_RMSEA.R | 1 - R/interpret_bf.R | 3 +- R/interpret_d.R | 2 - R/interpret_lavaan.R | 25 +++-- R/interpret_odds.R | 7 +- R/interpret_omega_sq.R | 3 +- R/interpret_r.R | 2 - R/is.standardized.R | 5 +- R/mellenbergh.test.R | 3 +- R/model_to_priors.R | 16 +-- R/mpe.R | 6 +- R/n_factors.R | 40 ++++--- R/odds_to_probs.R | 2 - R/overlap.R | 3 +- R/percentile.R | 2 - R/power_analysis.R | 22 ++-- R/probs_to_odds.R | 2 - R/refdata.R | 15 ++- R/remove_outliers.R | 12 +- R/rnorm_perfect.R | 2 - R/rope.R | 3 +- R/simulate.R | 7 +- R/standardize.R | 59 +++++----- docs/~$index.html | Bin 162 -> 0 bytes man/R2_LOO_Adjusted.Rd | 3 +- man/R2_nakagawa.Rd | 3 +- man/R2_tjur.Rd | 4 +- man/analyze.aov.Rd | 5 +- man/analyze.blavaan.Rd | 8 +- man/analyze.fa.Rd | 2 - man/analyze.glm.Rd | 3 +- man/analyze.glmerMod.Rd | 3 +- man/analyze.htest.Rd | 3 +- man/analyze.lavaan.Rd | 8 +- man/analyze.lm.Rd | 5 +- man/analyze.lmerModLmerTest.Rd | 3 +- man/analyze.principal.Rd | 2 - man/analyze.stanreg.Rd | 14 ++- man/assess.Rd | 3 +- man/correlation.Rd | 9 +- man/crawford.test.Rd | 5 +- man/crawford.test.freq.Rd | 1 - man/crawford_dissociation.test.Rd | 1 - man/create_intervals.Rd | 12 +- man/dprime.Rd | 24 ++-- man/find_best_model.lavaan.Rd | 44 ++++++++ man/find_best_model.lmerModLmerTest.Rd | 3 +- man/find_best_model.stanreg.Rd | 4 +- man/find_combinations.formula.Rd | 1 - man/find_matching_string.Rd | 1 - man/find_random_effects.Rd | 1 - man/find_season.Rd | 1 - man/format_formula.Rd | 6 +- man/get_R2.glm.Rd | 5 +- man/get_R2.lm.Rd | 3 +- man/get_R2.merMod.Rd | 7 +- man/get_R2.stanreg.Rd | 3 +- man/get_cfa_model.Rd | 5 +- man/get_contrasts.Rd | 15 ++- man/get_data.Rd | 19 ++-- man/get_formula.Rd | 6 +- man/get_graph.psychobject_correlation.Rd | 4 +- man/get_info.Rd | 4 +- man/get_info.lm.Rd | 3 +- man/get_info.lmerModLmerTest.Rd | 3 +- man/get_loadings_max.Rd | 1 - man/get_means.Rd | 11 +- man/get_predicted.glm.Rd | 16 +-- man/get_predicted.lm.Rd | 17 +-- man/get_predicted.merMod.Rd | 39 ++++--- man/get_predicted.stanreg.Rd | 31 +++--- man/golden.Rd | 1 - man/hdi.Rd | 1 - man/interpret_R2.Rd | 5 +- man/interpret_R2_posterior.Rd | 1 - man/interpret_RMSEA.Rd | 1 - man/interpret_bf.Rd | 3 +- man/interpret_d.Rd | 1 - man/interpret_d_posterior.Rd | 1 - man/interpret_lavaan.blavaan.Rd | 19 ++++ man/interpret_lavaan.lavaan.Rd | 16 +++ man/interpret_odds.Rd | 3 +- man/interpret_odds_posterior.Rd | 1 - man/interpret_omega_sq.Rd | 3 +- man/interpret_r.Rd | 1 - man/interpret_r_posterior.Rd | 1 - man/is.standardized.Rd | 1 - man/mellenbergh.test.Rd | 1 - man/model_to_priors.Rd | 16 +-- man/mpe.Rd | 4 +- man/n_factors.Rd | 1 - man/odds_to_d.Rd | 3 +- man/odds_to_probs.Rd | 2 - man/omega_sq.Rd | 1 - man/overlap.Rd | 1 - man/percentile.Rd | 1 - man/percentile_to_z.Rd | 1 - man/plot_loadings.Rd | 1 - man/power_analysis.Rd | 14 ++- man/probs_to_odds.Rd | 2 - man/refdata.Rd | 13 ++- man/reorder_matrix.Rd | 1 - man/rnorm_perfect.Rd | 2 - man/rope.Rd | 1 - man/simulate_data_regression.Rd | 5 +- man/standardize.data.frame.Rd | 14 +-- man/standardize.glm.Rd | 5 +- man/standardize.lm.Rd | 5 +- man/standardize.numeric.Rd | 6 +- man/standardize.stanreg.Rd | 7 +- 154 files changed, 870 insertions(+), 950 deletions(-) delete mode 100644 docs/~$index.html create mode 100644 man/find_best_model.lavaan.Rd create mode 100644 man/interpret_lavaan.blavaan.Rd create mode 100644 man/interpret_lavaan.lavaan.Rd diff --git a/NAMESPACE b/NAMESPACE index 0f99a33..8d8df30 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -14,6 +14,7 @@ S3method(analyze,lmerModLmerTest) S3method(analyze,principal) S3method(analyze,stanreg) S3method(as.data.frame,density) +S3method(find_best_model,lavaan) S3method(find_best_model,lmerModLmerTest) S3method(find_best_model,stanreg) S3method(find_combinations,formula) diff --git a/R/analyze.anova.R b/R/analyze.anova.R index ab31f7f..43fe0a6 100644 --- a/R/analyze.anova.R +++ b/R/analyze.anova.R @@ -11,30 +11,29 @@ #' @examples #' \dontrun{ #' library(psycho) -#' +#' #' df <- psycho::affective -#' +#' #' x <- aov(df$Tolerating ~ df$Salary) #' x <- aov(df$Tolerating ~ df$Salary * df$Sex) -#' +#' #' x <- anova(lm(df$Tolerating ~ df$Salary * df$Sex)) -#' -#' +#' +#' #' summary(analyze(x)) #' print(analyze(x)) -#' +#' #' df <- psycho::emotion %>% #' mutate(Recall = ifelse(Recall == TRUE, 1, 0)) %>% #' group_by(Participant_ID, Emotion_Condition) %>% #' summarise(Recall = sum(Recall) / n()) -#' -#' x <- aov(Recall ~ Emotion_Condition + Error(Participant_ID), data=df) -#' x <- anova(lmerTest::lmer(Recall ~ Emotion_Condition + (1|Participant_ID), data=df)) +#' +#' x <- aov(Recall ~ Emotion_Condition + Error(Participant_ID), data = df) +#' x <- anova(lmerTest::lmer(Recall ~ Emotion_Condition + (1 | Participant_ID), data = df)) #' analyze(x) #' summary(x) #' } -#' -#' +#' #' @references #' \itemize{ #' \item{Levine, T. R., & Hullett, C. R. (2002). Eta squared, partial eta squared, and misreporting of effect size in communication research. Human Communication Research, 28(4), 612-625.} @@ -289,14 +288,13 @@ analyze.aovlist <- analyze.aov #' #' @examples #' library(psycho) -#' +#' #' df <- psycho::affective -#' +#' #' x <- aov(df$Tolerating ~ df$Salary) #' x <- aov(df$Tolerating ~ df$Salary * df$Sex) -#' +#' #' omega_sq(x) -#' #' @seealso http://stats.stackexchange.com/a/126520 #' #' @author Arnoud Plantinga diff --git a/R/analyze.blavaan.R b/R/analyze.blavaan.R index 88778bc..b7d2039 100644 --- a/R/analyze.blavaan.R +++ b/R/analyze.blavaan.R @@ -12,16 +12,12 @@ #' @examples #' library(psycho) #' library(lavaan) -#' -#' model <- ' visual =~ x1 + x2 + x3 -#' textual =~ x4 + x5 + x6 -#' speed =~ x7 + x8 + x9 ' -#' x <- lavaan::cfa(model, data=HolzingerSwineford1939) -#' +#' +#' model <- " visual =~ x1 + x2 + x3\ntextual =~ x4 + x5 + x6\nspeed =~ x7 + x8 + x9 " +#' x <- lavaan::cfa(model, data = HolzingerSwineford1939) +#' #' rez <- analyze(x) #' print(rez) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @seealso @@ -30,14 +26,14 @@ #' @importFrom lavaan parameterEstimates fitmeasures #' #' @export -analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { +analyze.blavaan <- function(x, CI = 90, standardize = FALSE, ...) { fit <- x # Processing # ------------- values <- list() - values$CI = CI + values$CI <- CI # Fit measures values$Fit_Measures <- interpret_lavaan(fit) @@ -47,14 +43,16 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { # ------------- computations <- .get_info_computations(fit) fitmeasures <- values$Fit_Measures$text - text <- paste0("A Bayesian model was fitted (", - computations, - "). The fit indices are as following: ", - fitmeasures) + text <- paste0( + "A Bayesian model was fitted (", + computations, + "). The fit indices are as following: ", + fitmeasures + ) # Summary # ------------- - summary <- .summary_blavaan(fit, CI=CI, standardize=standardize) + summary <- .summary_blavaan(fit, CI = CI, standardize = standardize) # Plot # ------------- @@ -74,13 +72,15 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { #' @keywords internal .get_info_computations <- function(fit) { chains <- blavaan::blavInspect(fit, "n.chains") - sample = fit@external$sample - warmup = fit@external$burnin - text = paste0(chains, - " chains, each with iter = ", - sample, - "; warmup = ", - warmup) + sample <- fit@external$sample + warmup <- fit@external$burnin + text <- paste0( + chains, + " chains, each with iter = ", + sample, + "; warmup = ", + warmup + ) return(text) } @@ -88,16 +88,20 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { #' @keywords internal -.process_blavaan <- function(fit, standardize=FALSE, CI=90){ +.process_blavaan <- function(fit, standardize = FALSE, CI = 90) { # Get relevant rows - PE <- parameterEstimates(fit, se = FALSE, ci=FALSE, remove.eq = FALSE, remove.system.eq = TRUE, - remove.ineq = FALSE, remove.def = FALSE, - add.attributes = TRUE) - if(!("group" %in% names(PE))) PE$group <- 1 + PE <- parameterEstimates(fit, + se = FALSE, ci = FALSE, remove.eq = FALSE, remove.system.eq = TRUE, + remove.ineq = FALSE, remove.def = FALSE, + add.attributes = TRUE + ) + if (!("group" %in% names(PE))) PE$group <- 1 newpt <- fit@ParTable pte2 <- which(newpt$free > 0) - relevant_rows <- match(with(newpt, paste(lhs[pte2], op[pte2], rhs[pte2], group[pte2], sep="")), - paste(PE$lhs, PE$op, PE$rhs, PE$group, sep="")) + relevant_rows <- match( + with(newpt, paste(lhs[pte2], op[pte2], rhs[pte2], group[pte2], sep = "")), + paste(PE$lhs, PE$op, PE$rhs, PE$group, sep = "") + ) # Priors priors <- rep(NA, nrow(PE)) @@ -108,12 +112,12 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { # Posterior - if(standardize == FALSE){ + if (standardize == FALSE) { posteriors <- blavaan::blavInspect(fit, "draws") %>% as.matrix() %>% as.data.frame() names(posteriors) <- names(lavaan::coef(fit)) - } else{ + } else { posteriors <- blavaan::standardizedposterior(fit) %>% as.data.frame() } @@ -127,7 +131,7 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { Effect <- c() CI_lower <- c() CI_higher <- c() - for(effect in names(posteriors)){ + for (effect in names(posteriors)) { posterior <- posteriors[[effect]] Effect <- c(Effect, effect) MPE <- c(MPE, mpe(posterior)$MPE) @@ -137,10 +141,9 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { CI_values <- HDI(posterior, prob = CI / 100) CI_lower <- c(CI_lower, CI_values$values$HDImin) CI_higher <- c(CI_higher, CI_values$values$HDImax) - } - if(standardize == FALSE){ + if (standardize == FALSE) { Effects <- rep(NA, nrow(PE)) Effects[relevant_rows] <- Effect MPEs <- rep(NA, nrow(PE)) @@ -153,7 +156,7 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { CI_lowers[relevant_rows] <- CI_lower CI_highers <- rep(NA, nrow(PE)) CI_highers[relevant_rows] <- CI_higher - } else{ + } else { Effects <- Effect MPEs <- MPE Medians <- Median @@ -162,13 +165,15 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { CI_highers <- CI_higher } - data <- data.frame("Effect" = Effects, - "Median" = Medians, - "MAD" = MADs, - "MPE" = MPEs, - "CI_lower" = CI_lowers, - "CI_higher" = CI_highers, - "Prior" = priors) + data <- data.frame( + "Effect" = Effects, + "Median" = Medians, + "MAD" = MADs, + "MPE" = MPEs, + "CI_lower" = CI_lowers, + "CI_higher" = CI_highers, + "Prior" = priors + ) return(data) } @@ -176,31 +181,35 @@ analyze.blavaan <- function(x, CI=90, standardize=FALSE,...) { #' @keywords internal -.summary_blavaan <- function(fit, CI=90, standardize=FALSE){ - - solution <- lavaan::parameterEstimates(fit, se = TRUE, ci=TRUE, standardized=FALSE, level = CI/100) +.summary_blavaan <- function(fit, CI = 90, standardize = FALSE) { + solution <- lavaan::parameterEstimates(fit, se = TRUE, ci = TRUE, standardized = FALSE, level = CI / 100) solution <- solution %>% - rename("From" = "rhs", - "To" = "lhs", - "Operator" = "op", - "Coef" = "est", - "SE" = "se", - "CI_lower" = "ci.lower", - "CI_higher" = "ci.upper") %>% + rename( + "From" = "rhs", + "To" = "lhs", + "Operator" = "op", + "Coef" = "est", + "SE" = "se", + "CI_lower" = "ci.lower", + "CI_higher" = "ci.upper" + ) %>% mutate(Type = dplyr::case_when( Operator == "=~" ~ "Loading", - Operator == "~" ~ "Regression", + Operator == "~" ~ "Regression", Operator == "~~" ~ "Correlation", - TRUE ~ NA_character_)) %>% + TRUE ~ NA_character_ + )) %>% select(one_of(c("To", "Operator", "From", "Type"))) %>% mutate_("Effect" = "as.character(paste0(To, Operator, From))") %>% - full_join(.process_blavaan(fit, CI=CI, standardize=standardize) %>% - mutate_("Effect" = "as.character(Effect)"), by="Effect") %>% + full_join(.process_blavaan(fit, CI = CI, standardize = standardize) %>% + mutate_("Effect" = "as.character(Effect)"), by = "Effect") %>% select_("-Effect") %>% - mutate_("Median" = "replace_na(Median, 1)", - "MAD" = "replace_na(MAD, 0)", - "MPE" = "replace_na(MPE, 100)") %>% + mutate_( + "Median" = "replace_na(Median, 1)", + "MAD" = "replace_na(MAD, 0)", + "MPE" = "replace_na(MPE, 100)" + ) %>% select(one_of(c("From", "Operator", "To", "Median", "MAD", "CI_lower", "CI_higher", "MPE", "Prior", "Type"))) %>% dplyr::filter_("Operator != '~1'") diff --git a/R/analyze.fa.R b/R/analyze.fa.R index 0cffc48..30c6d47 100644 --- a/R/analyze.fa.R +++ b/R/analyze.fa.R @@ -12,15 +12,13 @@ #' @examples #' library(psycho) #' library(psych) -#' +#' #' x <- psych::fa(psych::Thurstone.33, 2) -#' +#' #' results <- analyze(x) #' print(results) #' summary(results) #' plot(results) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export @@ -109,11 +107,11 @@ analyze.fa <- function(x, labels = NULL, treshold = "max", ...) { #' @examples #' \dontrun{ #' library(psycho) -#' +#' #' x <- psych::fa(psych::Thurstone.33, 2) #' format_loadings(x) #' } -#' +#' #' @import dplyr #' @export format_loadings <- function(x, labels = NULL) { @@ -163,12 +161,11 @@ format_loadings <- function(x, labels = NULL) { #' @examples #' \dontrun{ #' library(psycho) -#' +#' #' x <- psych::fa(psych::Thurstone.33, 2) #' get_loadings_max(format_loadings(x)$loadings) #' } -#' -#' +#' #' @import dplyr #' @export get_loadings_max <- function(loadings) { @@ -194,14 +191,13 @@ get_loadings_max <- function(loadings) { #' @examples #' \dontrun{ #' library(psycho) -#' +#' #' x <- psych::fa(psych::Thurstone.33, 2) #' loadings <- format_loadings(x)$loadings -#' get_cfa_model(loadings, treshold="max") -#' get_cfa_model(loadings, treshold=0.1) +#' get_cfa_model(loadings, treshold = "max") +#' get_cfa_model(loadings, treshold = 0.1) #' } -#' -#' +#' #' @import dplyr #' @export get_cfa_model <- function(loadings, treshold = "max") { @@ -240,12 +236,11 @@ get_cfa_model <- function(loadings, treshold = "max") { #' @examples #' \dontrun{ #' library(psycho) -#' +#' #' x <- psych::fa(psych::Thurstone.33, 2) #' plot_loadings(format_loadings(x)$loadings) #' } -#' -#' +#' #' @import dplyr #' @export plot_loadings <- function(loadings) { @@ -265,8 +260,3 @@ plot_loadings <- function(loadings) { return(p) } - - - - - diff --git a/R/analyze.glm.R b/R/analyze.glm.R index ecccf8c..28792f6 100644 --- a/R/analyze.glm.R +++ b/R/analyze.glm.R @@ -11,12 +11,11 @@ #' #' @examples #' library(psycho) -#' fit <- glm(Sex ~ Adjusting, data=psycho::affective, family="binomial") -#' +#' fit <- glm(Sex ~ Adjusting, data = psycho::affective, family = "binomial") +#' #' results <- analyze(fit) #' summary(results) #' print(results) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @references Nakagawa, S., & Schielzeth, H. (2013). A general and simple method for obtaining R2 from generalized linear mixed-effects models. Methods in Ecology and Evolution, 4(2), 133-142. diff --git a/R/analyze.glmerMod.R b/R/analyze.glmerMod.R index 7bd311c..07109b8 100644 --- a/R/analyze.glmerMod.R +++ b/R/analyze.glmerMod.R @@ -13,15 +13,14 @@ #' \dontrun{ #' library(psycho) #' library(lme4) -#' -#' fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") -#' +#' +#' fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") +#' #' results <- analyze(fit) #' summary(results) #' print(results) #' } -#' -#' +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @references Nakagawa, S., & Schielzeth, H. (2013). A general and simple method for obtaining R2 from generalized linear mixed-effects models. Methods in Ecology and Evolution, 4(2), 133-142. diff --git a/R/analyze.htest.R b/R/analyze.htest.R index a424643..ae16acf 100644 --- a/R/analyze.htest.R +++ b/R/analyze.htest.R @@ -10,18 +10,17 @@ #' #' @examples #' library(psycho) -#' +#' #' df <- psycho::affective -#' +#' #' x <- t.test(df$Tolerating, df$Adjusting) #' x <- t.test(df$Tolerating ~ df$Sex) -#' x <- t.test(df$Tolerating, mu=2) +#' x <- t.test(df$Tolerating, mu = 2) #' x <- cor.test(df$Tolerating, df$Adjusting) -#' +#' #' results <- analyze(x) #' summary(results) #' print(results) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @import dplyr diff --git a/R/analyze.lavaan.R b/R/analyze.lavaan.R index 1816497..a9fd6ef 100644 --- a/R/analyze.lavaan.R +++ b/R/analyze.lavaan.R @@ -12,16 +12,12 @@ #' @examples #' library(psycho) #' library(lavaan) -#' -#' model <- ' visual =~ x1 + x2 + x3 -#' textual =~ x4 + x5 + x6 -#' speed =~ x7 + x8 + x9 ' -#' x <- lavaan::cfa(model, data=HolzingerSwineford1939) -#' +#' +#' model <- " visual =~ x1 + x2 + x3\ntextual =~ x4 + x5 + x6\nspeed =~ x7 + x8 + x9 " +#' x <- lavaan::cfa(model, data = HolzingerSwineford1939) +#' #' rez <- analyze(x) #' print(rez) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @seealso @@ -31,14 +27,14 @@ #' @importFrom lavaan parameterEstimates fitmeasures #' #' @export -analyze.lavaan <- function(x, CI=95, standardize=FALSE, ...) { +analyze.lavaan <- function(x, CI = 95, standardize = FALSE, ...) { fit <- x # Processing # ------------- values <- list() - values$CI = CI + values$CI <- CI # Fit measures values$Fit_Measures <- interpret_lavaan(fit) @@ -48,7 +44,7 @@ analyze.lavaan <- function(x, CI=95, standardize=FALSE, ...) { # Summary # ------------- - summary <- .summary_lavaan(fit, CI=CI, standardize=standardize) + summary <- .summary_lavaan(fit, CI = CI, standardize = standardize) # Plot # ------------- @@ -74,45 +70,40 @@ analyze.lavaan <- function(x, CI=95, standardize=FALSE, ...) { #' @keywords internal -.summary_lavaan <- function(fit, CI=95, standardize=FALSE){ - - if(standardize == FALSE){ - solution <- lavaan::parameterEstimates(fit, se=TRUE, standardized=standardize, level = CI/100) - }else{ - solution <- lavaan::standardizedsolution(fit, se=TRUE, level = CI/100) %>% +.summary_lavaan <- function(fit, CI = 95, standardize = FALSE) { + if (standardize == FALSE) { + solution <- lavaan::parameterEstimates(fit, se = TRUE, standardized = standardize, level = CI / 100) + } else { + solution <- lavaan::standardizedsolution(fit, se = TRUE, level = CI / 100) %>% rename_("est" = "est.std") } solution <- solution %>% - rename("From" = "rhs", - "To" = "lhs", - "Operator" = "op", - "Coef" = "est", - "SE" = "se", - "p" = "pvalue", - "CI_lower" = "ci.lower", - "CI_higher" = "ci.upper") %>% + rename( + "From" = "rhs", + "To" = "lhs", + "Operator" = "op", + "Coef" = "est", + "SE" = "se", + "p" = "pvalue", + "CI_lower" = "ci.lower", + "CI_higher" = "ci.upper" + ) %>% mutate(Type = dplyr::case_when( Operator == "=~" ~ "Loading", - Operator == "~" ~ "Regression", + Operator == "~" ~ "Regression", Operator == "~~" ~ "Correlation", - TRUE ~ NA_character_)) %>% + TRUE ~ NA_character_ + )) %>% mutate_("p" = "replace_na(p, 0)") - if("group" %in% names(solution)){ + if ("group" %in% names(solution)) { solution <- solution %>% rename("Group" = "group") %>% select(one_of(c("Group", "From", "Operator", "To", "Coef", "SE", "CI_lower", "CI_higher", "p", "Type"))) - } else{ + } else { solution <- select(solution, one_of(c("From", "Operator", "To", "Coef", "SE", "CI_lower", "CI_higher", "p", "Type"))) } return(solution) } - - - - - - - diff --git a/R/analyze.lm.R b/R/analyze.lm.R index 5f8166a..0e1a86b 100644 --- a/R/analyze.lm.R +++ b/R/analyze.lm.R @@ -11,13 +11,12 @@ #' #' @examples #' library(psycho) -#' fit <- lm(Sepal.Length ~ Sepal.Width, data=iris) -#' fit <- lm(Sepal.Length ~ Sepal.Width * Species, data=iris) -#' +#' fit <- lm(Sepal.Length ~ Sepal.Width, data = iris) +#' fit <- lm(Sepal.Length ~ Sepal.Width * Species, data = iris) +#' #' results <- analyze(fit) #' summary(results) #' print(results) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @import dplyr diff --git a/R/analyze.lmerModLmerTest.R b/R/analyze.lmerModLmerTest.R index 966d142..828196c 100644 --- a/R/analyze.lmerModLmerTest.R +++ b/R/analyze.lmerModLmerTest.R @@ -12,12 +12,11 @@ #' @examples #' library(psycho) #' library(lmerTest) -#' fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) -#' +#' fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + (1 | Species), data = iris) +#' #' results <- analyze(fit) #' summary(results) #' print(results) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @references Nakagawa, S., & Schielzeth, H. (2013). A general and simple method for obtaining R2 from generalized linear mixed-effects models. Methods in Ecology and Evolution, 4(2), 133-142. diff --git a/R/analyze.principal.R b/R/analyze.principal.R index 8cfa693..2b80261 100644 --- a/R/analyze.principal.R +++ b/R/analyze.principal.R @@ -12,15 +12,13 @@ #' @examples #' library(psycho) #' library(psych) -#' +#' #' x <- psych::pca(psych::Thurstone.33, 2) -#' +#' #' results <- analyze(x) #' print(results) #' summary(results) #' plot(results) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/analyze.stanreg.R b/R/analyze.stanreg.R index b6c0743..96f0c1c 100644 --- a/R/analyze.stanreg.R +++ b/R/analyze.stanreg.R @@ -25,31 +25,33 @@ #' \dontrun{ #' library(psycho) #' library(rstanarm) -#' +#' #' data <- attitude -#' fit <- rstanarm::stan_glm(rating ~ advance + privileges, data=data) -#' -#' results <- analyze(fit, effsize=TRUE) +#' fit <- rstanarm::stan_glm(rating ~ advance + privileges, data = data) +#' +#' results <- analyze(fit, effsize = TRUE) #' summary(results) #' print(results) #' plot(results) -#' -#' -#' fit <- rstanarm::stan_lmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) +#' +#' +#' fit <- rstanarm::stan_lmer(Sepal.Length ~ Sepal.Width + (1 | Species), data = iris) #' results <- analyze(fit) #' summary(results) -#' +#' #' fit <- rstanarm::stan_glm(Sex ~ Adjusting, -#' data=psycho::affective, family="binomial") +#' data = psycho::affective, family = "binomial" +#' ) #' results <- analyze(fit) #' summary(results) -#' -#' fit <- rstanarm::stan_glmer(Sex ~ Adjusting + (1|Salary), -#' data=psycho::affective, family="binomial") +#' +#' fit <- rstanarm::stan_glmer(Sex ~ Adjusting + (1 | Salary), +#' data = psycho::affective, family = "binomial" +#' ) #' results <- analyze(fit) #' summary(results) #' } -#' +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @seealso diff --git a/R/assess.R b/R/assess.R index aa5cadd..ce1ad76 100644 --- a/R/assess.R +++ b/R/assess.R @@ -21,10 +21,9 @@ #' @return output #' #' @examples -#' result <- assess(patient=124, mean=100, sd=15, n=100) +#' result <- assess(patient = 124, mean = 100, sd = 15, n = 100) #' print(result) #' plot(result) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @details Until relatively recently the standard way of testing for a difference between a case and controls was to convert the case’s score to a z score using the control sample mean and standard deviation (SD). If z was less than -1.645 (i.e., below 95% of the controls) then it was concluded that the case was significantly lower than controls. However, this method has serious disadvantages (Crawford and Garthwaite, 2012). diff --git a/R/bayes_cor.R b/R/bayes_cor.R index d16b1e5..f3de50e 100644 --- a/R/bayes_cor.R +++ b/R/bayes_cor.R @@ -16,11 +16,11 @@ #' library(psycho) #' x <- psycho::affective$Concealing #' y <- psycho::affective$Tolerating -#' +#' #' bayes_cor.test(x, y) #' summary(bayes_cor.test(x, y)) #' } -#' +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom BayesFactor correlationBF posterior @@ -152,13 +152,13 @@ bayes_cor.test <- function(x, y, CI = 90, iterations = 10000, effsize_rules_r = #' @examples #' \dontrun{ #' library(psycho) -#' +#' #' df <- psycho::affective #' cor <- bayes_cor(df) #' summary(cor) #' print(cor) #' plot(cor) -#' +#' #' df <- select(psycho::affective, Adjusting, Tolerating) #' df2 <- select(psycho::affective, -Adjusting, -Tolerating) #' cor <- bayes_cor(df, df2) @@ -166,7 +166,7 @@ bayes_cor.test <- function(x, y, CI = 90, iterations = 10000, effsize_rules_r = #' print(cor) #' plot(cor) #' } -#' +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' @export bayes_cor <- function(df, df2 = NULL, reorder = TRUE) { @@ -314,11 +314,10 @@ bayes_cor <- function(df, df2 = NULL, reorder = TRUE) { #' #' @examples #' library(psycho) -#' +#' #' r <- correlation(iris) #' r <- r$values$r #' r <- reorder_matrix(r) -#' #' @importFrom stats as.dist hclust #' @export reorder_matrix <- function(mat, dmat = NULL) { diff --git a/R/cite_packages.R b/R/cite_packages.R index 5cce8e3..85fc05d 100644 --- a/R/cite_packages.R +++ b/R/cite_packages.R @@ -9,24 +9,26 @@ #' library(psycho) #' cite_packages(sessionInfo()) #' } -#' +#' #' @author \href{https://github.com/DominiqueMakowski}{Dominique Makowski} #' #' @export -cite_packages <- function(session){ +cite_packages <- function(session) { pkgs <- session$otherPkgs citations <- c() - for(pkg_name in names(pkgs)){ + for (pkg_name in names(pkgs)) { pkg <- pkgs[[pkg_name]] citation <- format(citation(pkg_name))[[2]] %>% stringr::str_split("\n") %>% flatten() %>% - paste(collapse="SPLIT") %>% + paste(collapse = "SPLIT") %>% stringr::str_split("SPLITSPLIT") - i = 1 - while(stringr::str_detect(citation[[1]][i], "To cite ")){i = i + 1} + i <- 1 + while (stringr::str_detect(citation[[1]][i], "To cite ")) { + i <- i + 1 + } citation <- citation[[1]][i] %>% diff --git a/R/correlation.R b/R/correlation.R index 3a479ff..1846f85 100644 --- a/R/correlation.R +++ b/R/correlation.R @@ -23,19 +23,20 @@ #' #' @examples #' df <- attitude -#' +#' #' # Normal correlations #' results <- psycho::correlation(df) #' print(results) #' plot(results) -#' +#' #' # Partial correlations with correction -#' results <- psycho::correlation(df, type="partial", -#' method="spearman", -#' adjust="holm") +#' results <- psycho::correlation(df, +#' type = "partial", +#' method = "spearman", +#' adjust = "holm" +#' ) #' print(results) #' plot(results) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom stats na.omit p.adjust cor runif diff --git a/R/crawford.test.R b/R/crawford.test.R index 7e04a10..f7f6d16 100644 --- a/R/crawford.test.R +++ b/R/crawford.test.R @@ -23,14 +23,13 @@ #' #' @examples #' library(psycho) -#' -#' crawford.test(patient = 125, mean=100, sd=15, n=100) -#' plot(crawford.test(patient = 80, mean=100, sd=15, n=100)) -#' +#' +#' crawford.test(patient = 125, mean = 100, sd = 15, n = 100) +#' plot(crawford.test(patient = 80, mean = 100, sd = 15, n = 100)) +#' #' crawford.test(patient = 10, controls = c(0, -2, 5, 2, 1, 3, -4, -2)) #' test <- crawford.test(patient = 7, controls = c(0, -2, 5, -6, 0, 3, -4, -2)) #' plot(test) -#' #' @author Dominique Makowski #' #' @importFrom stats pnorm var approx rchisq @@ -225,10 +224,9 @@ crawford.test <- function(patient, #' #' @examples #' library(psycho) -#' +#' #' crawford.test.freq(patient = 10, controls = c(0, -2, 5, 2, 1, 3, -4, -2)) #' crawford.test.freq(patient = 7, controls = c(0, -2, 5, 2, 1, 3, -4, -2)) -#' #' @author Dan Mirman, Dominique Makowski #' #' @importFrom stats pt sd diff --git a/R/crawford_dissociation.test.R b/R/crawford_dissociation.test.R index bbee6f4..715a7d1 100644 --- a/R/crawford_dissociation.test.R +++ b/R/crawford_dissociation.test.R @@ -13,14 +13,13 @@ #' #' @examples #' library(psycho) -#' +#' #' case_X <- 142 #' case_Y <- 7 #' controls_X <- c(100, 125, 89, 105, 109, 99) #' controls_Y <- c(7, 8, 9, 6, 7, 10) -#' +#' #' crawford_dissociation.test(case_X, case_Y, controls_X, controls_Y) -#' #' @author Dominique Makowski #' #' @importFrom stats sd pt diff --git a/R/create_intervals.R b/R/create_intervals.R index 4e04cd9..0e15e30 100644 --- a/R/create_intervals.R +++ b/R/create_intervals.R @@ -11,17 +11,15 @@ #' #' @examples #' library(psycho) -#' +#' #' x <- rnorm(100, 0, 1) -#' -#' create_intervals(x, n=4) -#' create_intervals(x, n=4, equal_range=FALSE) -#' create_intervals(x, length=1) -#' -#' create_intervals(x, n=4, labels="median") -#' create_intervals(x, n=4, labels=FALSE) -#' -#' +#' +#' create_intervals(x, n = 4) +#' create_intervals(x, n = 4, equal_range = FALSE) +#' create_intervals(x, length = 1) +#' +#' create_intervals(x, n = 4, labels = "median") +#' create_intervals(x, n = 4, labels = FALSE) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom ggplot2 cut_interval cut_number diff --git a/R/dprime.R b/R/dprime.R index 6e58ac2..18bb257 100644 --- a/R/dprime.R +++ b/R/dprime.R @@ -27,26 +27,28 @@ #' @examples #' library(psycho) -#' +#' #' n_hit <- 9 #' n_fa <- 2 #' n_miss <- 1 #' n_cr <- 7 -#' +#' #' indices <- psycho::dprime(n_hit, n_fa, n_miss, n_cr) -#' -#' -#' df <- data.frame(Participant = c("A", "B", "C"), -#' n_hit = c(1, 2, 5), -#' n_fa = c(6, 8, 1)) -#' -#' indices <- psycho::dprime(n_hit=df$n_hit, -#' n_fa=df$n_fa, -#' n_targets=10, -#' n_distractors=10, -#' adjusted=FALSE) -#' -#' +#' +#' +#' df <- data.frame( +#' Participant = c("A", "B", "C"), +#' n_hit = c(1, 2, 5), +#' n_fa = c(6, 8, 1) +#' ) +#' +#' indices <- psycho::dprime( +#' n_hit = df$n_hit, +#' n_fa = df$n_fa, +#' n_targets = 10, +#' n_distractors = 10, +#' adjusted = FALSE +#' ) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom stats qnorm diff --git a/R/find_best_model.lavaan.R b/R/find_best_model.lavaan.R index e6d3b8d..1944a0f 100644 --- a/R/find_best_model.lavaan.R +++ b/R/find_best_model.lavaan.R @@ -3,6 +3,7 @@ #' Returns all combinations of lavaan models with their indices of fit. #' #' @param fit A lavaan object. +#' @param latent Copy/paste the part related to latent variables loadings. #' @param samples Number of random draws. #' @param verbose Show progress. #' @param ... Arguments passed to or from other methods. @@ -13,33 +14,33 @@ #' library(psycho) #' library(lavaan) #' -#' model <- ' visual =~ x1 + x2 + x3 -#' textual =~ x4 + x5 + x6 -#' speed =~ x7 + x8 + x9 -#' visual ~ textual -#' textual ~ speed' -#' fit <- lavaan::sem(model, data=HolzingerSwineford1939) -#' -#' models <- find_best_model.lavaan(fit, latent="visual =~ x1 + x2 + x3 -#' textual =~ x4 + x5 + x6 -#' speed =~ x7 + x8 + x9") +#' model <- " visual =~ x1 + x2 + x3 +#' textual =~ x4 + x5 + x6 +#' speed =~ x7 + x8 + x9 +#' visual ~ textual +#' textual ~ speed" +#' fit <- lavaan::sem(model, data = HolzingerSwineford1939) #' +#' models <- find_best_model(fit, latent = "visual =~ x1 + x2 + x3 +#' textual =~ x4 + x5 + x6 +#' speed =~ x7 + x8 + x9") #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @import dplyr #' -#' @method find_best_model stanreg +#' @method find_best_model lavaan #' @export -find_best_model.lavaan <- function(fit, latent="", samples=1000, verbose=FALSE, ...){ - - update_model <- function(fit, latent, model){ +find_best_model.lavaan <- function(fit, latent = "", samples = 1000, verbose = FALSE, ...) { + update_model <- function(fit, latent, model) { newfit <- update(fit, paste0(latent, "\n", model)) - indices <- data.frame(Value = fitMeasures(newfit)) %>% + indices <- data.frame(Value = lavaan::fitMeasures(newfit)) %>% tibble::rownames_to_column("Index") %>% tidyr::spread_("Index", "Value") %>% - cbind(data.frame(model = model, - n_links = nrow(lavaan::lavInspect(fit, "est")$beta))) + cbind(data.frame( + model = model, + n_links = nrow(lavaan::lavInspect(fit, "est")$beta) + )) return(indices) } @@ -47,116 +48,45 @@ find_best_model.lavaan <- function(fit, latent="", samples=1000, verbose=FALSE, # info <- fit@Model data <- data.frame() - for(outcome in vars){ + for (outcome in vars) { remaning_vars <- vars[!stringr::str_detect(vars, outcome)] combinations <- c() - for(y in 1:length(remaning_vars)){ - combinations <- c(combinations, combn(remaning_vars, y, simplify=FALSE)) + for (y in 1:length(remaning_vars)) { + combinations <- c(combinations, combn(remaning_vars, y, simplify = FALSE)) } combinations <- sapply(combinations, paste0, collapse = "+") combinations <- paste0(outcome, "~", combinations) x <- data.frame(A = combinations) names(x) <- c(outcome) - if(nrow(data) == 0){ + if (nrow(data) == 0) { data <- x - } else{ + } else { data <- cbind(data, x) } } - data <- rbind(data, head(data[NA,], 1)) + data <- rbind(data, head(data[NA, ], 1)) data[] <- lapply(data, as.character) data[is.na(data)] <- "" rownames(data) <- NULL out <- data.frame() - for(i in 1:samples){ - if(verbose==TRUE){ + for (i in 1:samples) { + if (verbose == TRUE) { cat(".") } model <- "" - for(var in names(data)){ + for (var in names(data)) { model <- paste0(model, sample(data[[var]], 1), "\n") } - if(!model %in% out$model){ + if (!model %in% out$model) { out <- tryCatch( rbind(out, update_model(fit, latent, model)), - error=function(e) out, - warning=function(w) out) + error = function(e) out, + warning = function(w) out + ) } } return(out) - } - - - - # vars <- row.names(lavaan::lavInspect(fit, "est")$lambda) - # - # possibilities <- list() - # for(var in vars){ - # remaning_vars <- paste(vars[!str_detect(vars, var)], collapse = "+") - # formula <- as.formula(paste(var, "~", remaning_vars)) - # combinations <- find_combinations(formula, interaction = FALSE) - # possibilities[[var]] <- combinations - # } - # - # - # - # get_solution <- function(possibilities, fit, out){ - # n <- sample(1:length(possibilities), 1) - # predictors <- sample(possibilities, n) - # model <- "" - # for(var in names(predictors)){ - # model <- paste0(model, sample(predictors[[var]], 1), "\n") - # if(model %in% out$model){ - # next - # } - # } - # newfit <- update(fit, model) - # indices <- data.frame(Value = fitMeasures(newfit)) %>% - # tibble::rownames_to_column("Index") %>% - # tidyr::spread_("Index", "Value") %>% - # cbind(data.frame(model = model, - # n_outcomes = n, - # n_links = nrow(lavaan::lavInspect(fit, "est")$beta))) - # out <- rbind(out, indices) - # return(out) - # } - # - # out <- data.frame() - # for(i in 1:samples){ - # if(verbose==TRUE){ - # print(paste0(round(i/samples*100), "%")) - # } - # out <- tryCatch( - # get_solution(possibilities, fit, out), - # error=function(e) out, - # warning=function(w) out) - # } - # - # out %>% - # distinct() %>% - # return() -# } - - - - - - - -# models <- apply(data, 1, paste, collapse="\n") - - -# possible_outcomes <- c() -# for(i in 1:length(vars)){ -# possible_outcomes <- c(possible_outcomes, combn(vars, i, simplify=FALSE)) -# } -# -# for(i in possible_outcomes){ -# -# # combinations <- refdata(possibilities) -# -# } - +} diff --git a/R/find_best_model.lmerModLmerTest.R b/R/find_best_model.lmerModLmerTest.R index 3a6a12d..5778f1f 100644 --- a/R/find_best_model.lmerModLmerTest.R +++ b/R/find_best_model.lmerModLmerTest.R @@ -14,16 +14,15 @@ #' \dontrun{ #' library(psycho) #' library(lmerTest) -#' +#' #' data <- standardize(iris) -#' fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + Petal.Length + (1|Species), data=data) -#' +#' fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + Petal.Length + (1 | Species), data = data) +#' #' best <- find_best_model(fit) #' best_formula <- best$formula #' best$table -#' #' } -#' +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom stats update diff --git a/R/find_best_model.stanreg.R b/R/find_best_model.stanreg.R index ac58b70..9c807da 100644 --- a/R/find_best_model.stanreg.R +++ b/R/find_best_model.stanreg.R @@ -22,18 +22,18 @@ #' \dontrun{ #' library(psycho) #' library(rstanarm) -#' +#' #' data <- standardize(attitude) -#' fit <- rstanarm::stan_glm(rating ~ advance + privileges, data=data) -#' +#' fit <- rstanarm::stan_glm(rating ~ advance + privileges, data = data) +#' #' best <- find_best_model(fit) #' best_formula <- best$formula #' best$table -#' +#' #' # To deactivate Kfold evaluation -#' best <- find_best_model(fit, K=0) +#' best <- find_best_model(fit, K = 0) #' } -#' +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom rstanarm loo kfold bayes_R2 diff --git a/R/find_combinations.R b/R/find_combinations.R index 5ed79a8..8915ad6 100644 --- a/R/find_combinations.R +++ b/R/find_combinations.R @@ -39,13 +39,12 @@ find_combinations <- function(object, ...) { #' #' @examples #' library(psycho) -#' +#' #' f <- as.formula("Y ~ A + B + C + D") #' f <- as.formula("Y ~ A + B + C + D + (1|E)") #' f <- as.formula("Y ~ A + B + C + D + (1|E) + (1|F)") -#' +#' #' find_combinations(f) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @method find_combinations formula @@ -78,8 +77,7 @@ find_combinations.formula <- function(object, interaction = TRUE, fixed = NULL, lapply( 1:n, function(i) combn(1:n, i, simplify = FALSE) - ) - , + ), recursive = FALSE ) diff --git a/R/find_distance_cluster.R b/R/find_distance_cluster.R index cfe4fdc..d5cdc89 100644 --- a/R/find_distance_cluster.R +++ b/R/find_distance_cluster.R @@ -9,9 +9,8 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -find_distance_cluster <- function(df, km){ - - myDist <- function(p1, p2) sqrt((p1[,1]-p2[,1])^2+(p1[,2]-p2[,2])^2) +find_distance_cluster <- function(df, km) { + myDist <- function(p1, p2) sqrt((p1[, 1] - p2[, 1])^2 + (p1[, 2] - p2[, 2])^2) data <- df %>% as.data.frame() %>% @@ -20,8 +19,8 @@ find_distance_cluster <- function(df, km){ n_clusters <- nrow(km$centers) data$Distance <- NA - for(clust in 1:n_clusters){ - data$Distance[km$cluster==clust] <- myDist(data[km$cluster==clust,], km$centers[clust,,drop=FALSE]) + for (clust in 1:n_clusters) { + data$Distance[km$cluster == clust] <- myDist(data[km$cluster == clust, ], km$centers[clust, , drop = FALSE]) } return(data$Distance) diff --git a/R/find_highest_density_point.R b/R/find_highest_density_point.R index 52c8a28..e455319 100644 --- a/R/find_highest_density_point.R +++ b/R/find_highest_density_point.R @@ -9,9 +9,9 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -find_highest_density_point <- function(x, precision=1e+03){ +find_highest_density_point <- function(x, precision = 1e+03) { d <- x %>% - density(n=precision) %>% + density(n = precision) %>% as.data.frame() y <- d$x[which.max(d$y)] return(y) diff --git a/R/find_matching_string.R b/R/find_matching_string.R index a4ae7b6..9b965d0 100644 --- a/R/find_matching_string.R +++ b/R/find_matching_string.R @@ -9,7 +9,6 @@ #' @examples #' library(psycho) #' find_matching_string("Hwo rea ouy", c("How are you", "Not this word", "Nice to meet you")) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/find_random_effects.R b/R/find_random_effects.R index e72f79c..1c05da0 100644 --- a/R/find_random_effects.R +++ b/R/find_random_effects.R @@ -5,7 +5,6 @@ #' @examples #' library(psycho) #' find_random_effects("Y ~ X + (1|Group)") -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom stringr str_remove_all diff --git a/R/find_season.R b/R/find_season.R index a9beedb..84e70e7 100644 --- a/R/find_season.R +++ b/R/find_season.R @@ -12,10 +12,9 @@ #' #' @examples #' library(psycho) -#' +#' #' dates <- c("2012-02-15", "2017-05-15", "2009-08-15", "1912-11-15") #' find_season(dates) -#' #' @author Josh O'Brien #' #' @seealso diff --git a/R/formatting.R b/R/formatting.R index f74d651..b2dfed0 100644 --- a/R/formatting.R +++ b/R/formatting.R @@ -120,13 +120,11 @@ format_p <- function(pvalues, stars = TRUE) { #' @examples #' library(psycho) #' library(lme4) -#' -#' fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") -#' fit <- lm(hp ~ wt, data=mtcars) -#' +#' +#' fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") +#' fit <- lm(hp ~ wt, data = mtcars) +#' #' format_formula(get_formula(fit)) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/get_R2.R b/R/get_R2.R index bb0b8e2..ccfed88 100644 --- a/R/get_R2.R +++ b/R/get_R2.R @@ -29,10 +29,9 @@ get_R2 <- function(fit, ...) { #' \dontrun{ #' library(psycho) #' -#' fit <- lm(Tolerating ~ Adjusting, data=psycho::affective) +#' fit <- lm(Tolerating ~ Adjusting, data = psycho::affective) #' #' get_R2(fit) -#' #' } #' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} @@ -59,11 +58,10 @@ get_R2.lm <- function(fit, ...) { #' \dontrun{ #' library(psycho) #' -#' fit <- glm(vs ~ wt, data=mtcars, family="binomial") -#' fit <- glm(Sex ~ Adjusting, data=psycho::affective, family="binomial") +#' fit <- glm(vs ~ wt, data = mtcars, family = "binomial") +#' fit <- glm(Sex ~ Adjusting, data = psycho::affective, family = "binomial") #' #' get_R2(fit) -#' #' } #' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} @@ -96,10 +94,9 @@ get_R2.glm <- function(fit, method = "nakagawa", ...) { #' library(psycho) #' library(rstanarm) #' -#' fit <- rstanarm::stan_glm(Adjusting ~ Tolerating, data=psycho::affective) +#' fit <- rstanarm::stan_glm(Adjusting ~ Tolerating, data = psycho::affective) #' #' get_R2(fit) -#' #' } #' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} @@ -150,11 +147,12 @@ get_R2.stanreg <- function(fit, silent = FALSE, ...) { #' \dontrun{ #' library(psycho) #' -#' fit <- lmerTest::lmer(Tolerating ~ Adjusting + (1|Sex), data=psycho::affective) -#' fit <- lme4::glmer(Sex ~ Adjusting + (1|Salary), data=na.omit(psycho::affective), family="binomial") +#' fit <- lmerTest::lmer(Tolerating ~ Adjusting + (1 | Sex), +#' data = psycho::affective) +#' fit <- lme4::glmer(Sex ~ Adjusting + (1 | Salary), +#' data = na.omit(psycho::affective), family = "binomial") #' #' get_R2(fit) -#' #' } #' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} @@ -178,10 +176,9 @@ get_R2.merMod <- function(fit, ...) { #' \dontrun{ #' library(psycho) #' -#' fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) +#' fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + (1 | Species), data = iris) #' #' R2_nakagawa(fit) -#' #' } #' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} @@ -214,10 +211,9 @@ R2_nakagawa <- function(fit) { #' library(rstanarm) #' #' data <- attitude -#' fit <- rstanarm::stan_glm(rating ~ advance + privileges, data=data) +#' fit <- rstanarm::stan_glm(rating ~ advance + privileges, data = data) #' #' R2_LOO_Adjusted(fit) -#' #' } #' #' @author \href{https://github.com/strengejacke}{Daniel Luedecke} @@ -244,7 +240,7 @@ R2_LOO_Adjusted <- function(fit) { psis_object <- loo::psis(log_ratios = -ll, r_eff = r_eff) ypredloo <- loo::E_loo(ypred, psis_object, log_ratios = -ll)$value - if(length(ypredloo) != length(y)){ + if (length(ypredloo) != length(y)) { warning("Something went wrong in the Loo-adjusted R2 computation.") return(NA) } @@ -267,10 +263,8 @@ R2_LOO_Adjusted <- function(fit) { #' library(psycho) #' library(lme4) #' -#' fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") +#' fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") #' R2_tjur(fit) -#' -#' #' @author \href{https://github.com/strengejacke}{Daniel Lüdecke} #' #' @import dplyr diff --git a/R/get_contrasts.R b/R/get_contrasts.R index 49145a4..b140fcc 100644 --- a/R/get_contrasts.R +++ b/R/get_contrasts.R @@ -21,19 +21,18 @@ #' library(psycho) #' require(lmerTest) #' require(rstanarm) -#' -#' fit <- lm(Adjusting ~ Birth_Season * Salary, data=affective) +#' +#' fit <- lm(Adjusting ~ Birth_Season * Salary, data = affective) #' get_contrasts(fit) -#' -#' fit <- lm(Adjusting ~ Birth_Season * Salary, data=affective) -#' get_contrasts(fit, adjust="bonf") -#' -#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1|Salary), data=affective) -#' get_contrasts(fit, formula="Birth_Season") -#' -#' fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data=affective) -#' get_contrasts(fit, formula="Birth_Season", ROPE_bounds=c(-0.1, 0.1)) -#' +#' +#' fit <- lm(Adjusting ~ Birth_Season * Salary, data = affective) +#' get_contrasts(fit, adjust = "bonf") +#' +#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1 | Salary), data = affective) +#' get_contrasts(fit, formula = "Birth_Season") +#' +#' fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data = affective) +#' get_contrasts(fit, formula = "Birth_Season", ROPE_bounds = c(-0.1, 0.1)) #' } #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' diff --git a/R/get_data.R b/R/get_data.R index 0a9e951..cb82921 100644 --- a/R/get_data.R +++ b/R/get_data.R @@ -9,22 +9,23 @@ #' \dontrun{ #' library(tidyverse) #' library(psycho) -#' +#' #' df <- mtcars %>% -#' mutate(cyl = as.factor(cyl), -#' gear = as.factor(gear)) -#' -#' fit <- lm(wt ~ mpg , data=df) -#' fit <- lm(wt ~ cyl, data=df) -#' fit <- lm(wt ~ mpg * cyl, data=df) -#' fit <- lm(wt ~ cyl * gear, data=df) -#' fit <- lmerTest::lmer(wt ~ mpg * gear + (1|cyl), data=df) -#' fit <- rstanarm::stan_lmer(wt ~ mpg * gear + (1|cyl), data=df) -#' +#' mutate( +#' cyl = as.factor(cyl), +#' gear = as.factor(gear) +#' ) +#' +#' fit <- lm(wt ~ mpg, data = df) +#' fit <- lm(wt ~ cyl, data = df) +#' fit <- lm(wt ~ mpg * cyl, data = df) +#' fit <- lm(wt ~ cyl * gear, data = df) +#' fit <- lmerTest::lmer(wt ~ mpg * gear + (1 | cyl), data = df) +#' fit <- rstanarm::stan_lmer(wt ~ mpg * gear + (1 | cyl), data = df) +#' #' get_data(fit) -#' #' } -#' +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' @export get_data <- function(fit, ...) { diff --git a/R/get_formula.R b/R/get_formula.R index 87c2e8f..99ad77f 100644 --- a/R/get_formula.R +++ b/R/get_formula.R @@ -16,13 +16,11 @@ #' @examples #' library(psycho) #' library(lme4) -#' -#' fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") -#' fit <- lm(hp ~ wt, data=mtcars) -#' +#' +#' fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") +#' fit <- lm(hp ~ wt, data = mtcars) +#' #' get_formula(fit) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/get_graph.R b/R/get_graph.R index 9015579..47bb6cd 100644 --- a/R/get_graph.R +++ b/R/get_graph.R @@ -56,71 +56,76 @@ get_graph <- function(fit, ...) { #' #' #' @export -get_graph.lavaan <- function(fit, links=c("Regression", "Correlation", "Loading"), standardize=FALSE, threshold_Coef=NULL, threshold_p=NULL, threshold_MPE=NULL, digits=2, CI="default", labels_CI=TRUE, ...){ +get_graph.lavaan <- function(fit, links = c("Regression", "Correlation", "Loading"), standardize = FALSE, threshold_Coef = NULL, threshold_p = NULL, threshold_MPE = NULL, digits = 2, CI = "default", labels_CI = TRUE, ...) { # https://www.r-bloggers.com/ggplot2-sem-models-with-tidygraph-and-ggraph/ - if(labels_CI==TRUE){ - if(CI != "default"){ - results <- analyze(fit, CI=CI, standardize=standardize) - } else{ - results <- analyze(fit, standardize=standardize) + if (labels_CI == TRUE) { + if (CI != "default") { + results <- analyze(fit, CI = CI, standardize = standardize) + } else { + results <- analyze(fit, standardize = standardize) } - } else{ - results <- analyze(fit, standardize=standardize) + } else { + results <- analyze(fit, standardize = standardize) } summary <- summary(results) CI <- results$values$CI # Check what type of model - if(class(fit) %in% c("blavaan")){ + if (class(fit) %in% c("blavaan")) { summary$Coef <- summary$Median - if(is.null(threshold_MPE)){ + if (is.null(threshold_MPE)) { threshold_MPE <- -1 } summary <- summary %>% filter_("MPE >= threshold_MPE") - - } else if(class(fit) %in% c("lavaan")){ - if(is.null(threshold_p)){ + } else if (class(fit) %in% c("lavaan")) { + if (is.null(threshold_p)) { threshold_p <- 1.1 } summary <- summary %>% filter_("p <= threshold_p") - } else{ + } else { stop(paste("Error in UseMethod('plot_lavaan') : no applicable method for 'plot_lavaan' applied to an object of class", class(fit))) } # Deal with thresholds - if(is.null(threshold_Coef)){ - threshold_Coef <- min(abs(summary$Coef))-1 + if (is.null(threshold_Coef)) { + threshold_Coef <- min(abs(summary$Coef)) - 1 } # Edge properties edges <- summary %>% mutate_("abs_coef" = "abs(Coef)") %>% - filter_('Type %in% c(links)', - "From != To", - "abs_coef >= threshold_Coef") %>% + filter_( + "Type %in% c(links)", + "From != To", + "abs_coef >= threshold_Coef" + ) %>% select(-one_of("abs_coef")) %>% - rename_("to" = "To", - "from" = "From") + rename_( + "to" = "To", + "from" = "From" + ) # Labels - if(labels_CI == TRUE){ + if (labels_CI == TRUE) { edges <- edges %>% - mutate_('Label' = 'paste0(format_digit(Coef, digits), + mutate_("Label" = 'paste0(format_digit(Coef, digits), ", ", CI, "% CI [", format_digit(CI_lower, digits), ", ", format_digit(CI_higher, digits), "]")') - } else{ + } else { edges <- edges %>% - mutate_('Label' = 'format_digit(Coef, digits)') + mutate_("Label" = "format_digit(Coef, digits)") } edges <- edges %>% - mutate_('Label_Regression' = "ifelse(Type=='Regression', Label, '')", - 'Label_Correlation' = "ifelse(Type=='Correlation', Label, '')", - 'Label_Loading' = "ifelse(Type=='Loading', Label, '')") + mutate_( + "Label_Regression" = "ifelse(Type=='Regression', Label, '')", + "Label_Correlation" = "ifelse(Type=='Correlation', Label, '')", + "Label_Loading" = "ifelse(Type=='Loading', Label, '')" + ) edges <- edges[colSums(!is.na(edges)) > 0] # Identify latent variables for nodes @@ -133,10 +138,12 @@ get_graph.lavaan <- function(fit, links=c("Regression", "Correlation", "Loading" # Node properties nodes <- summary %>% - filter_("From == To", - "From %in% nodes_list") %>% + filter_( + "From == To", + "From %in% nodes_list" + ) %>% mutate_("Name" = "From") %>% - left_join(latent_nodes, by="Name") %>% + left_join(latent_nodes, by = "Name") %>% mutate_("Latent" = "if_else(is.na(Latent), FALSE, Latent)") %>% select(one_of(c("Name", "Latent"))) @@ -163,7 +170,7 @@ get_graph.lavaan <- function(fit, links=c("Regression", "Correlation", "Loading" #' #' #' @export -get_graph.fa <- function(fit, threshold_Coef=NULL, digits=2, ...){ +get_graph.fa <- function(fit, threshold_Coef = NULL, digits = 2, ...) { edges <- summary(analyze(fit)) %>% gather("To", "Coef", -one_of("N", "Item", "Label")) %>% rename_("From" = "Item") %>% @@ -172,8 +179,8 @@ get_graph.fa <- function(fit, threshold_Coef=NULL, digits=2, ...){ filter() # Deal with thresholds - if(is.null(threshold_Coef)){ - threshold_Coef <- min(abs(edges$Coef))-1 + if (is.null(threshold_Coef)) { + threshold_Coef <- min(abs(edges$Coef)) - 1 } edges <- edges %>% @@ -183,7 +190,6 @@ get_graph.fa <- function(fit, threshold_Coef=NULL, digits=2, ...){ distinct_("Name") return(list(nodes = nodes, edges = edges)) - } @@ -203,8 +209,7 @@ get_graph.fa <- function(fit, threshold_Coef=NULL, digits=2, ...){ #' #' #' @export -get_graph.psychobject_correlation <- function(fit, ...){ - +get_graph.psychobject_correlation <- function(fit, ...) { vars <- row.names(fit$values$r) r <- fit$values$r %>% @@ -212,15 +217,17 @@ get_graph.psychobject_correlation <- function(fit, ...){ tibble::rownames_to_column("from") %>% tidyr::gather("to", "r", vars) - if("p" %in% names(fit$values)){ + if ("p" %in% names(fit$values)) { r <- r %>% full_join( fit$values$p %>% as.data.frame() %>% tibble::rownames_to_column("from") %>% - tidyr::gather("to", "p", vars), by = c("from", "to")) + tidyr::gather("to", "p", vars), + by = c("from", "to") + ) } - r <- filter(r, !from == to) + r <- filter_(r, "!from == to") return(r) } diff --git a/R/get_info.R b/R/get_info.R index 1b4ffa9..84856a8 100644 --- a/R/get_info.R +++ b/R/get_info.R @@ -11,13 +11,11 @@ #' @examples #' library(psycho) #' library(lme4) -#' -#' fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") -#' +#' +#' fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") +#' #' info <- get_info(fit) #' info -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export @@ -46,13 +44,13 @@ get_info <- function(x, ...) { #' @examples #' library(psycho) #' library(lme4) -#' -#' fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") -#' +#' +#' fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") +#' #' info <- get_info(fit) #' info -#' -# +#' +#' # #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export @@ -114,13 +112,13 @@ get_info.lmerMod <- get_info.lmerModLmerTest #' @examples #' library(psycho) #' library(lme4) -#' -#' fit <- lm(vs ~ wt, data=mtcars, family="binomial") -#' +#' +#' fit <- lm(vs ~ wt, data = mtcars, family = "binomial") +#' #' info <- get_info(fit) #' info -#' -# +#' +#' # #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/get_means.R b/R/get_means.R index 798da42..b6c3dd4 100644 --- a/R/get_means.R +++ b/R/get_means.R @@ -17,17 +17,16 @@ #' library(psycho) #' require(lmerTest) #' require(rstanarm) -#' -#' -#' fit <- glm(Sex ~ Birth_Season, data=affective, family="binomial") +#' +#' +#' fit <- glm(Sex ~ Birth_Season, data = affective, family = "binomial") #' get_means(fit) -#' -#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1|Salary), data=affective) -#' get_means(fit, formula="Birth_Season") -#' -#' fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data=affective) -#' get_means(fit, formula="Birth_Season") -#' +#' +#' fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1 | Salary), data = affective) +#' get_means(fit, formula = "Birth_Season") +#' +#' fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data = affective) +#' get_means(fit, formula = "Birth_Season") #' } #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' diff --git a/R/get_predicted.glm.R b/R/get_predicted.glm.R index 8ee73b7..2d43f88 100644 --- a/R/get_predicted.glm.R +++ b/R/get_predicted.glm.R @@ -16,18 +16,20 @@ #' \dontrun{ #' library(psycho) #' library(ggplot2) -#' -#' fit <- glm(Sex ~ Adjusting, data=affective, family="binomial") -#' +#' +#' fit <- glm(Sex ~ Adjusting, data = affective, family = "binomial") +#' #' refgrid <- psycho::refdata(affective, "Adjusting") -#' predicted <- get_predicted(fit, newdata=refgrid) -#' -#' ggplot(predicted, aes(x=Adjusting, y=Sex_Predicted)) + +#' predicted <- get_predicted(fit, newdata = refgrid) +#' +#' ggplot(predicted, aes(x = Adjusting, y = Sex_Predicted)) + #' geom_line() + -#' geom_ribbon(aes(ymin=Sex_CI_2.5, -#' ymax=Sex_CI_97.5), -#' alpha=0.1) -#' +#' geom_ribbon(aes( +#' ymin = Sex_CI_2.5, +#' ymax = Sex_CI_97.5 +#' ), +#' alpha = 0.1 +#' ) #' } #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' diff --git a/R/get_predicted.lm.R b/R/get_predicted.lm.R index f99fd1f..2cce683 100644 --- a/R/get_predicted.lm.R +++ b/R/get_predicted.lm.R @@ -15,19 +15,20 @@ #' \dontrun{ #' library(psycho) #' library(ggplot2) -#' -#' fit <- lm(Tolerating ~ Adjusting, data=affective) -#' +#' +#' fit <- lm(Tolerating ~ Adjusting, data = affective) +#' #' refgrid <- psycho::refdata(affective, "Adjusting") -#' predicted <- get_predicted(fit, newdata=refgrid) -#' -#' ggplot(predicted, aes(x=Adjusting, y=Tolerating_Predicted)) + +#' predicted <- get_predicted(fit, newdata = refgrid) +#' +#' ggplot(predicted, aes(x = Adjusting, y = Tolerating_Predicted)) + #' geom_line() + -#' geom_ribbon(aes(ymin=Tolerating_CI_2.5, -#' ymax=Tolerating_CI_97.5), -#' alpha=0.1) -#' -#' +#' geom_ribbon(aes( +#' ymin = Tolerating_CI_2.5, +#' ymax = Tolerating_CI_97.5 +#' ), +#' alpha = 0.1 +#' ) #' } #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' diff --git a/R/get_predicted.merMod.R b/R/get_predicted.merMod.R index c62defe..4e7146b 100644 --- a/R/get_predicted.merMod.R +++ b/R/get_predicted.merMod.R @@ -20,48 +20,53 @@ #' \dontrun{ #' library(psycho) #' library(ggplot2) -#' -#' fit <- lmerTest::lmer(Tolerating ~ Adjusting + (1|Salary), data=affective) -#' +#' +#' fit <- lmerTest::lmer(Tolerating ~ Adjusting + (1 | Salary), data = affective) +#' #' refgrid <- psycho::refdata(affective, "Adjusting") -#' predicted <- get_predicted(fit, newdata=refgrid) -#' -#' ggplot(predicted, aes(x=Adjusting, y=Tolerating_Predicted)) + +#' predicted <- get_predicted(fit, newdata = refgrid) +#' +#' ggplot(predicted, aes(x = Adjusting, y = Tolerating_Predicted)) + #' geom_line() -#' -#' predicted <- get_predicted(fit, newdata=refgrid, prob=0.95, iter=100) # Takes a long time -#' -#' ggplot(predicted, aes(x=Adjusting, y=Tolerating_Predicted)) + +#' +#' predicted <- get_predicted(fit, newdata = refgrid, prob = 0.95, iter = 100) # Takes a long time +#' +#' ggplot(predicted, aes(x = Adjusting, y = Tolerating_Predicted)) + #' geom_line() + -#' geom_ribbon(aes(ymin=Tolerating_CI_2.5, -#' ymax=Tolerating_CI_97.5), -#' alpha=0.1) -#' -#' -#' -#' fit <- lme4::glmer(Sex ~ Adjusting + (1|Salary), data=affective, family="binomial") -#' +#' geom_ribbon(aes( +#' ymin = Tolerating_CI_2.5, +#' ymax = Tolerating_CI_97.5 +#' ), +#' alpha = 0.1 +#' ) +#' +#' +#' +#' fit <- lme4::glmer(Sex ~ Adjusting + (1 | Salary), data = affective, family = "binomial") +#' #' refgrid <- psycho::refdata(affective, "Adjusting") -#' predicted <- get_predicted(fit, newdata=refgrid) -#' -#' ggplot(predicted, aes(x=Adjusting, y=Sex_Predicted)) + +#' predicted <- get_predicted(fit, newdata = refgrid) +#' +#' ggplot(predicted, aes(x = Adjusting, y = Sex_Predicted)) + #' geom_line() -#' -#' predicted <- get_predicted(fit, newdata=refgrid, prob=0.95, iter=100) # Takes a long time -#' -#' ggplot(predicted, aes(x=Adjusting, y=Sex_Predicted)) + +#' +#' predicted <- get_predicted(fit, newdata = refgrid, prob = 0.95, iter = 100) # Takes a long time +#' +#' ggplot(predicted, aes(x = Adjusting, y = Sex_Predicted)) + #' geom_line() + -#' geom_ribbon(aes(ymin=Sex_CI_2.5, -#' ymax=Sex_CI_97.5), -#' alpha=0.1) -#' +#' geom_ribbon(aes( +#' ymin = Sex_CI_2.5, +#' ymax = Sex_CI_97.5 +#' ), +#' alpha = 0.1 +#' ) #' } #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom dplyr bind_cols #' @importFrom tibble rownames_to_column #' @export -get_predicted.merMod <- function(fit, newdata="model", prob=NULL, odds_to_probs=TRUE, iter=100, seed=NULL, re.form="default", use.u=FALSE, ...) { +get_predicted.merMod <- function(fit, newdata = "model", prob = NULL, odds_to_probs = TRUE, iter = 100, seed = NULL, re.form = "default", use.u = FALSE, ...) { # Extract names @@ -88,12 +93,12 @@ get_predicted.merMod <- function(fit, newdata="model", prob=NULL, odds_to_probs= # Deal with random - if(!is.na(re.form)){ - if(re.form=="default"){ + if (!is.na(re.form)) { + if (re.form == "default") { # Check if all predictors are in variables - if(all(get_info(fit)$predictors %in% names(newdata))){ + if (all(get_info(fit)$predictors %in% names(newdata))) { re.form <- NULL - } else{ + } else { re.form <- NA } } diff --git a/R/get_predicted.stanreg.R b/R/get_predicted.stanreg.R index 676e6b1..f2d2a8a 100644 --- a/R/get_predicted.stanreg.R +++ b/R/get_predicted.stanreg.R @@ -23,29 +23,34 @@ #' library(psycho) #' library(ggplot2) #' require(rstanarm) -#' -#' fit <- rstanarm::stan_glm(Tolerating ~ Adjusting, data=affective) -#' +#' +#' fit <- rstanarm::stan_glm(Tolerating ~ Adjusting, data = affective) +#' #' refgrid <- psycho::refdata(affective, "Adjusting") -#' predicted <- get_predicted(fit, newdata=refgrid) -#' -#' ggplot(predicted, aes(x=Adjusting, y=Tolerating_Median)) + +#' predicted <- get_predicted(fit, newdata = refgrid) +#' +#' ggplot(predicted, aes(x = Adjusting, y = Tolerating_Median)) + #' geom_line() + -#' geom_ribbon(aes(ymin=Tolerating_CI_5, -#' ymax=Tolerating_CI_95), -#' alpha=0.1) -#' -#' fit <- rstanarm::stan_glm(Sex ~ Adjusting, data=affective, family="binomial") -#' +#' geom_ribbon(aes( +#' ymin = Tolerating_CI_5, +#' ymax = Tolerating_CI_95 +#' ), +#' alpha = 0.1 +#' ) +#' +#' fit <- rstanarm::stan_glm(Sex ~ Adjusting, data = affective, family = "binomial") +#' #' refgrid <- psycho::refdata(affective, "Adjusting") -#' predicted <- get_predicted(fit, newdata=refgrid) -#' -#' ggplot(predicted, aes(x=Adjusting, y=Sex_Median)) + +#' predicted <- get_predicted(fit, newdata = refgrid) +#' +#' ggplot(predicted, aes(x = Adjusting, y = Sex_Median)) + #' geom_line() + -#' geom_ribbon(aes(ymin=Sex_CI_5, -#' ymax=Sex_CI_95), -#' alpha=0.1) -#' +#' geom_ribbon(aes( +#' ymin = Sex_CI_5, +#' ymax = Sex_CI_95 +#' ), +#' alpha = 0.1 +#' ) #' } #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' @@ -54,7 +59,7 @@ #' @importFrom dplyr bind_cols #' @importFrom tibble rownames_to_column #' @export -get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_probs = TRUE, keep_iterations = FALSE, draws = NULL, posterior_predict = FALSE, seed = NULL, transform = FALSE, re.form="default", ...) { +get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_probs = TRUE, keep_iterations = FALSE, draws = NULL, posterior_predict = FALSE, seed = NULL, transform = FALSE, re.form = "default", ...) { # Extract names predictors <- all.vars(as.formula(fit$formula)) @@ -80,17 +85,17 @@ get_predicted.stanreg <- function(fit, newdata = "model", prob = 0.9, odds_to_pr } # Deal with potential random - if(!is.na(re.form)){ - if(re.form=="default"){ - if(is.mixed(fit)){ + if (!is.na(re.form)) { + if (re.form == "default") { + if (is.mixed(fit)) { # Check if all predictors are in variables - if(all(get_info(fit)$predictors %in% names(newdata))){ + if (all(get_info(fit)$predictors %in% names(newdata))) { re.form <- NULL - } else{ + } else { re.form <- NA } } - } + } } # Generate draws ------------------------------------------------------- diff --git a/R/golden.R b/R/golden.R index 98e6eed..129fe1c 100644 --- a/R/golden.R +++ b/R/golden.R @@ -6,10 +6,9 @@ #' #' @examples #' library(psycho) -#' +#' #' golden() #' golden(8) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/hdi.R b/R/hdi.R index ab34344..4025a4a 100644 --- a/R/hdi.R +++ b/R/hdi.R @@ -7,16 +7,15 @@ #' #' @examples #' library(psycho) -#' +#' #' distribution <- rnorm(1000, 0, 1) #' HDI_values <- HDI(distribution) #' print(HDI_values) #' plot(HDI_values) #' summary(HDI_values) -#' +#' #' x <- matrix(rexp(200), 100) #' HDI_values <- HDI(x) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export @@ -126,7 +125,7 @@ HDImax <- function(x, prob = .95) { x <- sort(x) ci.index <- ceiling(prob * length(x)) nCIs <- length(x) - ci.index - ci.width <- purrr::map_dbl(1:nCIs, ~x[.x + ci.index] - x[.x]) + ci.width <- purrr::map_dbl(1:nCIs, ~ x[.x + ci.index] - x[.x]) HDImin <- x[which.min(ci.width)] HDImax <- x[which.min(ci.width) + ci.index] return(c(HDImin, HDImax)) diff --git a/R/interpret_R2.R b/R/interpret_R2.R index 95f3881..1fa505b 100644 --- a/R/interpret_R2.R +++ b/R/interpret_R2.R @@ -7,9 +7,8 @@ #' #' @examples #' library(psycho) -#' interpret_R2(x=0.42) -#' interpret_R2(x=c(0.42, 0.2, 0.9, 0)) -#' +#' interpret_R2(x = 0.42) +#' interpret_R2(x = c(0.42, 0.2, 0.9, 0)) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export @@ -33,7 +32,6 @@ interpret_R2 <- function(x, rules = "cohen1988") { #' library(psycho) #' posterior <- rnorm(1000, 0.4, 0.1) #' interpret_R2_posterior(posterior) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/interpret_RMSEA.R b/R/interpret_RMSEA.R index 58653d4..4a4f061 100644 --- a/R/interpret_RMSEA.R +++ b/R/interpret_RMSEA.R @@ -8,7 +8,6 @@ #' @examples #' library(psycho) #' interpret_RMSEA(0.04) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/interpret_bf.R b/R/interpret_bf.R index 23dae0b..da51db8 100644 --- a/R/interpret_bf.R +++ b/R/interpret_bf.R @@ -10,8 +10,7 @@ #' #' @examples #' library(psycho) -#' interpret_bf(x=10) -#' +#' interpret_bf(x = 10) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @references diff --git a/R/interpret_d.R b/R/interpret_d.R index 147a6c0..f856423 100644 --- a/R/interpret_d.R +++ b/R/interpret_d.R @@ -10,7 +10,6 @@ #' library(psycho) #' interpret_d(-0.42) #' interpret_d(-0.62) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export @@ -37,7 +36,6 @@ interpret_d <- function(x, direction = FALSE, rules = "cohen1988") { #' posterior <- rnorm(1000, 0.6, 0.05) #' interpret_d_posterior(posterior) #' interpret_d_posterior(rnorm(1000, 0.1, 1)) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/interpret_lavaan.R b/R/interpret_lavaan.R index 68f39f2..9c948f4 100644 --- a/R/interpret_lavaan.R +++ b/R/interpret_lavaan.R @@ -20,8 +20,13 @@ interpret_lavaan <- function(fit, ...) { #' Interpret fit measures of lavaan objects #' #' Interpret fit measures of lavaan objects +#' +#' @param fit lavaan or blavaan object. +#' @param ... Arguments passed to or from other methods. +#' +#' @importFrom lavaan fitmeasures #' @export -interpret_lavaan.lavaan <- function(fit, ...){ +interpret_lavaan.lavaan <- function(fit, ...) { values <- list() indices <- lavaan::fitmeasures(fit) @@ -98,10 +103,9 @@ interpret_lavaan.lavaan <- function(fit, ...){ } text <- paste(satisfactory, poor) - output <- list(text = text, summary = summary, values = values, plot="Not available yet") + output <- list(text = text, summary = summary, values = values, plot = "Not available yet") class(output) <- c("psychobject", "list") return(output) - } @@ -109,10 +113,14 @@ interpret_lavaan.lavaan <- function(fit, ...){ +#' Interpret fit measures of blavaan objects +#' +#' Interpret fit measures of blavaan objects +#' #' @param indices Vector of strings indicating which indices to report. Only works for bayesian objects for now. #' @inheritParams interpret_lavaan #' @export -interpret_lavaan.blavaan <- function(fit, indices=c("BIC", "DIC", "WAIC", "LOOIC"), ...){ +interpret_lavaan.blavaan <- function(fit, indices = c("BIC", "DIC", "WAIC", "LOOIC"), ...) { values <- list() indices <- lavaan::fitmeasures(fit) @@ -129,13 +137,10 @@ interpret_lavaan.blavaan <- function(fit, indices=c("BIC", "DIC", "WAIC", "LOOIC mutate_("Index" = "str_to_upper(Index)") # Text - relevant_indices <- summary[summary$Index %in% c("BIC", "DIC", "WAIC", "LOOIC"),] - text <- paste0(relevant_indices$Index, " = ", format_digit(relevant_indices$Value), collapse=", ") + relevant_indices <- summary[summary$Index %in% c("BIC", "DIC", "WAIC", "LOOIC"), ] + text <- paste0(relevant_indices$Index, " = ", format_digit(relevant_indices$Value), collapse = ", ") - output <- list(text = text, summary = summary, values = values, plot="Not available yet") + output <- list(text = text, summary = summary, values = values, plot = "Not available yet") class(output) <- c("psychobject", "list") return(output) - } - - diff --git a/R/interpret_odds.R b/R/interpret_odds.R index b5a90c7..e26c81c 100644 --- a/R/interpret_odds.R +++ b/R/interpret_odds.R @@ -9,8 +9,7 @@ #' #' @examples #' library(psycho) -#' interpret_odds(x=2) -#' +#' interpret_odds(x = 2) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @seealso http://imaging.mrc-cbu.cam.ac.uk/statswiki/FAQ/effectSize @@ -52,7 +51,6 @@ interpret_odds <- function(x, log = FALSE, direction = FALSE, rules = "chen2010" #' interpret_odds_posterior(posterior) #' interpret_odds_posterior(rnorm(1000, 0.1, 1)) #' interpret_odds_posterior(rnorm(1000, 3, 1.5)) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export @@ -214,8 +212,7 @@ interpret_odds_posterior <- function(posterior, log = FALSE, rules = "chen2010") #' #' @examples #' library(psycho) -#' odds_to_d(x=2) -#' +#' odds_to_d(x = 2) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @seealso https://www.meta-analysis.com/downloads/Meta-analysis%20Converting%20among%20effect%20sizes.pdf diff --git a/R/interpret_omega_sq.R b/R/interpret_omega_sq.R index 69e907f..6340362 100644 --- a/R/interpret_omega_sq.R +++ b/R/interpret_omega_sq.R @@ -7,8 +7,7 @@ #' #' @examples #' library(psycho) -#' interpret_omega_sq(x=0.05) -#' +#' interpret_omega_sq(x = 0.05) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @seealso http://imaging.mrc-cbu.cam.ac.uk/statswiki/FAQ/effectSize diff --git a/R/interpret_r.R b/R/interpret_r.R index 8cae11b..dc7042b 100644 --- a/R/interpret_r.R +++ b/R/interpret_r.R @@ -11,7 +11,6 @@ #' @examples #' library(psycho) #' interpret_r(-0.42) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @seealso Page 88 of APA's 6th Edition @@ -41,7 +40,6 @@ interpret_r <- function(x, direction = TRUE, strength = TRUE, rules = "cohen1988 #' library(psycho) #' posterior <- rnorm(1000, 0.5, 0.5) #' interpret_r_posterior(posterior) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @seealso Page 88 of APA's 6th Edition diff --git a/R/is.standardized.R b/R/is.standardized.R index aad5cdc..0c90ea0 100644 --- a/R/is.standardized.R +++ b/R/is.standardized.R @@ -7,13 +7,12 @@ #' #' @examples #' library(psycho) -#' +#' #' df <- psycho::affective #' is.standardized(df) -#' +#' #' dfZ <- psycho::standardize(df) #' is.standardized(dfZ) -#' #' @return bool. #' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/R/mellenbergh.test.R b/R/mellenbergh.test.R index 5851185..52fabc0 100644 --- a/R/mellenbergh.test.R +++ b/R/mellenbergh.test.R @@ -10,10 +10,9 @@ #' #' @examples #' library(psycho) -#' +#' #' mellenbergh.test(t0 = 4, t1 = 12, controls = c(0, -2, 5, 2, 1, 3, -4, -2)) #' mellenbergh.test(t0 = 8, t1 = 2, controls = 2.6) -#' #' @author Dominique Makowski #' #' @importFrom stats pnorm sd diff --git a/R/model_to_priors.R b/R/model_to_priors.R index 3189f8c..38ae815 100644 --- a/R/model_to_priors.R +++ b/R/model_to_priors.R @@ -9,22 +9,24 @@ #' library(rstanarm) #' library(psycho) #' -#' fit <- stan_glm(Sepal.Length ~ Petal.Width, data=iris) +#' fit <- stan_glm(Sepal.Length ~ Petal.Width, data = iris) #' priors <- model_to_priors(fit) -#' update(fit, prior=priors$prior) +#' update(fit, prior = priors$prior) #' -#' fit <- stan_glmer(Subjective_Valence ~ Emotion_Condition + (1|Participant_ID), data=psycho::emotion) +#' fit <- stan_glmer(Subjective_Valence ~ Emotion_Condition + (1 | Participant_ID), +#' data = psycho::emotion) #' priors <- model_to_priors(fit) #' #' fit1 <- stan_glm(Subjective_Valence ~ Emotion_Condition, -#' data=filter(psycho::emotion, Participant_ID == "1S")) +#' data = filter(psycho::emotion, Participant_ID == "1S") +#' ) #' #' fit2 <- stan_glm(Subjective_Valence ~ Emotion_Condition, -#' data=filter(psycho::emotion, Participant_ID == "1S"), -#' prior=priors$prior, prior_intercept=priors$prior_intercept) +#' data = filter(psycho::emotion, Participant_ID == "1S"), +#' prior = priors$prior, prior_intercept = priors$prior_intercept +#' ) #' } #' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @import dplyr diff --git a/R/mpe.R b/R/mpe.R index cf758f8..a6e6c61 100644 --- a/R/mpe.R +++ b/R/mpe.R @@ -9,14 +9,12 @@ #' @examples #' library(psycho) #' library(rstanarm) -#' -#' fit <- rstanarm::stan_glm(rating ~ advance, data=attitude) +#' +#' fit <- rstanarm::stan_glm(rating ~ advance, data = attitude) #' posterior <- psycho::analyze(fit)$values$effects$advance$posterior #' mpe <- psycho::mpe(posterior) #' print(mpe$MPE) #' print(mpe$values) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/n_factors.R b/R/n_factors.R index 7cc8c99..0973bf8 100644 --- a/R/n_factors.R +++ b/R/n_factors.R @@ -14,13 +14,12 @@ #' @examples #' df <- dplyr::select_if(attitude, is.numeric) #' results <- psycho::n_factors(df) -#' +#' #' summary(results) #' plot(results) -#' +#' #' # See details on methods #' psycho::values(results)$methods -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom qgraph cor_auto @@ -101,7 +100,7 @@ n_factors <- function(df, rotate = "varimax", fm = "minres", n = NULL) { "Exp.Variance" = "Prop", "Cum.Variance" = "Cumu" ) %>% - mutate_("n.Factors" = ~seq_len(nrow(nS$Analysis))) + mutate_("n.Factors" = ~ seq_len(nrow(nS$Analysis))) @@ -190,15 +189,15 @@ n_factors <- function(df, rotate = "varimax", fm = "minres", n = NULL) { eigenvalues <- results %>% group_by_("n_optimal") %>% - summarise_("n_method" = ~n()) %>% - mutate_("n_optimal" = ~factor(n_optimal, levels = seq_len(nrow(eigenvalues)))) %>% + summarise_("n_method" = ~ n()) %>% + mutate_("n_optimal" = ~ factor(n_optimal, levels = seq_len(nrow(eigenvalues)))) %>% complete_("n_optimal", fill = list(n_method = 0)) %>% arrange_("n_optimal") %>% rename_( "n.Factors" = "n_optimal", "n.Methods" = "n_method" ) %>% - mutate_("n.Factors" = ~as.integer(n.Factors)) %>% + mutate_("n.Factors" = ~ as.integer(n.Factors)) %>% left_join(eigenvalues, by = "n.Factors") %>% select_("-Exp.Variance") @@ -228,23 +227,36 @@ n_factors <- function(df, rotate = "varimax", fm = "minres", n = NULL) { # Text # ------------- - # Plural - if (best_n == 1) { - factor_text <- " factor " - } else { + # Deal with equality + if (length(best_n) > 1) { + best_n <- head(best_n, length(best_n) - 1) %>% + paste(collapse = ", ") %>% + paste(best_n[length(best_n)], sep = " and ") factor_text <- " factors " + n_methods <- unique(best_n_df$n.Methods) + best_n_methods <- paste0(paste(best_n_methods, collapse = "; "), "; respectively") + } else { + n_methods <- best_n_df$n.Methods + # Plural + if (best_n == 1) { + factor_text <- " factor " + } else { + factor_text <- " factors " + } } + + text <- paste0( "The choice of ", best_n, factor_text, "is supported by ", - best_n_df$n.Methods, + n_methods, " (out of ", round(nrow(results)), "; ", - round(best_n_df$n.Methods / nrow(results) * 100, 2), + round(n_methods / nrow(results) * 100, 2), "%) methods (", best_n_methods, ")." @@ -277,7 +289,7 @@ n_factors <- function(df, rotate = "varimax", fm = "minres", n = NULL) { size = 1 ) + scale_y_continuous(sec.axis = sec_axis( - trans = ~. * (max(plot_data$Cum.Variance) / max(plot_data$Eigenvalues)), + trans = ~ . * (max(plot_data$Cum.Variance) / max(plot_data$Eigenvalues)), name = "Cumulative Variance\n" )) + ylab("Eigenvalues\n") + diff --git a/R/odds_to_probs.R b/R/odds_to_probs.R index 84bcbed..7e65932 100644 --- a/R/odds_to_probs.R +++ b/R/odds_to_probs.R @@ -10,8 +10,6 @@ #' @examples #' library(psycho) #' odds_to_probs(-1.45) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom purrr keep discard diff --git a/R/overlap.R b/R/overlap.R index 5d7c631..f24057a 100644 --- a/R/overlap.R +++ b/R/overlap.R @@ -8,11 +8,10 @@ #' #' @examples #' library(psycho) -#' +#' #' x <- rnorm(100, 1, 0.5) #' y <- rnorm(100, 0, 1) #' overlap(x, y) -#' #' @author S. Venne #' #' @importFrom stats density diff --git a/R/percentile.R b/R/percentile.R index 69adb1b..ad66c45 100644 --- a/R/percentile.R +++ b/R/percentile.R @@ -5,7 +5,6 @@ #' @examples #' library(psycho) #' percentile(-1.96) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom stats pnorm @@ -24,7 +23,6 @@ percentile <- function(z_score) { #' @examples #' library(psycho) #' percentile_to_z(95) -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom stats pnorm diff --git a/R/power_analysis.R b/R/power_analysis.R index 9dc3ceb..05a0193 100644 --- a/R/power_analysis.R +++ b/R/power_analysis.R @@ -21,19 +21,21 @@ #' \dontrun{ #' library(dplyr) #' library(psycho) -#' -#' fit <- lm(Sepal.Length ~ Sepal.Width, data=iris) -#' -#' results <- power_analysis(fit, n_max=300, n_min=100, step=5, n_batch=20) -#' +#' +#' fit <- lm(Sepal.Length ~ Sepal.Width, data = iris) +#' +#' results <- power_analysis(fit, n_max = 300, n_min = 100, step = 5, n_batch = 20) +#' #' results %>% -#' filter(Variable=="Sepal.Width") %>% +#' filter(Variable == "Sepal.Width") %>% #' select(n, p) %>% #' group_by(n) %>% -#' summarise(p_median = median(p), -#' p_mad = mad(p)) -#' } -#' +#' summarise( +#' p_median = median(p), +#' p_mad = mad(p) +#' ) +#' } +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom stats model.frame diff --git a/R/probs_to_odds.R b/R/probs_to_odds.R index 211172b..d56c9b8 100644 --- a/R/probs_to_odds.R +++ b/R/probs_to_odds.R @@ -6,8 +6,6 @@ #' @examples #' library(psycho) #' probs_to_odds(0.75) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/refdata.R b/R/refdata.R index 7872dd1..a2047c2 100644 --- a/R/refdata.R +++ b/R/refdata.R @@ -11,19 +11,18 @@ #' #' @examples #' library(psycho) -#' +#' #' df <- psycho::affective -#' newdata <- refdata(df, target="Sex") -#' newdata <- refdata(df, target="Sex", factors="combinations") -#' newdata <- refdata(df, target=c("Sex", "Salary", "Tolerating"), length.out=3) -#' newdata <- refdata(df, target=c("Sex", "Salary", "Tolerating"), numerics=0) -#' +#' newdata <- refdata(df, target = "Sex") +#' newdata <- refdata(df, target = "Sex", factors = "combinations") +#' newdata <- refdata(df, target = c("Sex", "Salary", "Tolerating"), length.out = 3) +#' newdata <- refdata(df, target = c("Sex", "Salary", "Tolerating"), numerics = 0) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom purrr keep #' @import tidyr #' @export -refdata <- function(df, target = "all", length.out = 10, factors = "reference", numerics = "mean", na.rm=TRUE) { +refdata <- function(df, target = "all", length.out = 10, factors = "reference", numerics = "mean", na.rm = TRUE) { # Target if (all(target == "all") | ncol(df) == 1) { @@ -42,7 +41,7 @@ refdata <- function(df, target = "all", length.out = 10, factors = "reference", smart_summary <- function(x, numerics) { - if(na.rm == TRUE) x <- na.omit(x) + if (na.rm == TRUE) x <- na.omit(x) if (is.numeric(x)) { fun <- paste0(numerics, "(x)") diff --git a/R/remove_outliers.R b/R/remove_outliers.R index ffbc505..0fde152 100644 --- a/R/remove_outliers.R +++ b/R/remove_outliers.R @@ -10,8 +10,8 @@ #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export -remove_outliers <- function(df, target, threshold=qnorm(0.95), direction="both"){ - for(var in c(target)){ +remove_outliers <- function(df, target, threshold = qnorm(0.95), direction = "both") { + for (var in c(target)) { df <- .remove_outliers(df, var, threshold, direction) } return(df) @@ -23,15 +23,15 @@ remove_outliers <- function(df, target, threshold=qnorm(0.95), direction="both") #' @keywords internal -.remove_outliers <- function(df, target, threshold=qnorm(0.95), direction="both"){ +.remove_outliers <- function(df, target, threshold = qnorm(0.95), direction = "both") { df <- df %>% mutate_("outlier_criterion" = target) %>% - standardize(subset="outlier_criterion") - if(direction %in% c("both", "upper")){ + standardize(subset = "outlier_criterion") + if (direction %in% c("both", "upper")) { df <- df %>% filter_("outlier_criterion <= threshold") } - if(direction %in% c("both", "lower")){ + if (direction %in% c("both", "lower")) { df <- df %>% filter_("outlier_criterion >= -threshold") } diff --git a/R/rnorm_perfect.R b/R/rnorm_perfect.R index f55e1e7..e9d8c57 100644 --- a/R/rnorm_perfect.R +++ b/R/rnorm_perfect.R @@ -12,8 +12,6 @@ #' library(psycho) #' x <- rnorm_perfect(10) #' plot(density(x)) -#' -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @importFrom stats rnorm diff --git a/R/rope.R b/R/rope.R index d8e076e..9f705c7 100644 --- a/R/rope.R +++ b/R/rope.R @@ -12,11 +12,10 @@ #' #' @examples #' library(psycho) -#' +#' #' posterior <- rnorm(1000, 0, 0.01) #' results <- rope(posterior) #' results$decision -#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @export diff --git a/R/simulate.R b/R/simulate.R index fd6f3d9..5cb026d 100644 --- a/R/simulate.R +++ b/R/simulate.R @@ -8,12 +8,11 @@ #' #' @examples #' library(psycho) -#' -#' data <- simulate_data_regression(coefs=c(0.1, 0.8), sample=50, error=0) -#' fit <- lm(y ~ ., data=data) +#' +#' data <- simulate_data_regression(coefs = c(0.1, 0.8), sample = 50, error = 0) +#' fit <- lm(y ~ ., data = data) #' coef(fit) #' analyze(fit) -#' #' @details See https://stats.stackexchange.com/questions/59062/multiple-linear-regression-simulation #' #' @author TPArrow diff --git a/R/standardize.R b/R/standardize.R index d5428c8..ad7c1b7 100644 --- a/R/standardize.R +++ b/R/standardize.R @@ -51,10 +51,8 @@ standardize <- function(x, ...) { #' @param ... Arguments passed to or from other methods. #' #' @examples -#' standardize(x=c(1, 4, 6, 2)) -#' standardize(x=c(1, 4, 6, 2), normalize=TRUE) -#' -#' +#' standardize(x = c(1, 4, 6, 2)) +#' standardize(x = c(1, 4, 6, 2), normalize = TRUE) #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @@ -105,26 +103,26 @@ standardize.numeric <- function(x, normalize = FALSE, ...) { #' @examples #' \dontrun{ #' df <- data.frame( -#' Participant = as.factor(rep(1:25,each=4)), +#' Participant = as.factor(rep(1:25, each = 4)), #' Condition = base::rep_len(c("A", "B", "C", "D"), 100), #' V1 = rnorm(100, 30, .2), #' V2 = runif(100, 3, 5), #' V3 = rnorm(100, 100, 10) -#' ) -#' +#' ) +#' #' dfZ <- standardize(df) -#' dfZ <- standardize(df, except="V3") -#' dfZ <- standardize(df, except=c("V1", "V2")) -#' dfZ <- standardize(df, subset="V3") -#' dfZ <- standardize(df, subset=c("V1", "V2")) -#' dfZ <- standardize(df, normalize=TRUE) -#' +#' dfZ <- standardize(df, except = "V3") +#' dfZ <- standardize(df, except = c("V1", "V2")) +#' dfZ <- standardize(df, subset = "V3") +#' dfZ <- standardize(df, subset = c("V1", "V2")) +#' dfZ <- standardize(df, normalize = TRUE) +#' #' # Respects grouping #' dfZ <- df %>% #' dplyr::group_by(Participant) %>% #' standardize(df) #' } -#' +#' #' @author \href{https://dominiquemakowski.github.io/}{Dominique Makowski} #' #' @@ -232,14 +230,13 @@ standardize.data.frame <- function(x, subset = NULL, except = NULL, normalize = #' \dontrun{ #' library(psycho) #' library(rstanarm) -#' -#' fit <- rstanarm::stan_glm(Sepal.Length ~ Sepal.Width * Species, data=iris) -#' fit <- rstanarm::stan_glm(Sepal.Length ~ Sepal.Width * Species, data=standardize(iris)) +#' +#' fit <- rstanarm::stan_glm(Sepal.Length ~ Sepal.Width * Species, data = iris) +#' fit <- rstanarm::stan_glm(Sepal.Length ~ Sepal.Width * Species, data = standardize(iris)) #' posteriors <- standardize(fit) -#' posteriors <- standardize(fit, method="posterior") -#' +#' posteriors <- standardize(fit, method = "posterior") #' } -#' +#' #' @author \href{https://github.com/jgabry}{Jonah Gabry}, \href{https://github.com/bgoodri}{bgoodri} #' #' @seealso https://github.com/stan-dev/rstanarm/issues/298 @@ -300,13 +297,12 @@ standardize.stanreg <- function(x, method = "refit", ...) { #' @examples #' \dontrun{ #' library(psycho) -#' fit <- glm(Sex ~ Adjusting, data=psycho::affective, family="binomial") -#' fit <- lme4::glmer(Sex ~ Adjusting + (1|Sex), data=psycho::affective, family="binomial") -#' +#' fit <- glm(Sex ~ Adjusting, data = psycho::affective, family = "binomial") +#' fit <- lme4::glmer(Sex ~ Adjusting + (1 | Sex), data = psycho::affective, family = "binomial") +#' #' standardize(fit) -#' #' } -#' +#' #' @author Kamil Barton #' @importFrom stats model.frame model.response model.matrix #' @@ -353,18 +349,17 @@ standardize.glmerMod <- standardize.glm #' @examples #' \dontrun{ #' library(psycho) -#' +#' #' df <- mtcars %>% #' mutate(cyl = as.factor(cyl)) -#' -#' fit <- lm(wt ~ mpg * cyl, data=df) -#' fit <- lmerTest::lmer(wt ~ mpg * cyl + (1|gear), data=df) -#' +#' +#' fit <- lm(wt ~ mpg * cyl, data = df) +#' fit <- lmerTest::lmer(wt ~ mpg * cyl + (1 | gear), data = df) +#' #' summary(fit) #' standardize(fit) -#' #' } -#' +#' #' @author Kamil Barton #' @importFrom stats model.frame model.response model.matrix #' diff --git a/docs/~$index.html b/docs/~$index.html deleted file mode 100644 index dbf56053ba1df5f78a217c172771146e9a6dab72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 zcmd;d@lDLmFE7r{WFP@>GPp4KG9)r&GvqUrGZX`9i1tepUf*G`Vd&V9bbgisBLf4B ph8cZj!pl1hwhSE?pz<&pCVy>$_#Fm2hAu9KD4@wD45\% group_by(Participant_ID, Emotion_Condition) \%>\% summarise(Recall = sum(Recall) / n()) -x <- aov(Recall ~ Emotion_Condition + Error(Participant_ID), data=df) -x <- anova(lmerTest::lmer(Recall ~ Emotion_Condition + (1|Participant_ID), data=df)) +x <- aov(Recall ~ Emotion_Condition + Error(Participant_ID), data = df) +x <- anova(lmerTest::lmer(Recall ~ Emotion_Condition + (1 | Participant_ID), data = df)) analyze(x) summary(x) } - } \references{ \itemize{ diff --git a/man/analyze.blavaan.Rd b/man/analyze.blavaan.Rd index ecb3e32..d2af880 100644 --- a/man/analyze.blavaan.Rd +++ b/man/analyze.blavaan.Rd @@ -25,15 +25,11 @@ Analyze blavaan (SEM or CFA) objects. library(psycho) library(lavaan) -model <- ' visual =~ x1 + x2 + x3 - textual =~ x4 + x5 + x6 - speed =~ x7 + x8 + x9 ' -x <- lavaan::cfa(model, data=HolzingerSwineford1939) +model <- " visual =~ x1 + x2 + x3\\ntextual =~ x4 + x5 + x6\\nspeed =~ x7 + x8 + x9 " +x <- lavaan::cfa(model, data = HolzingerSwineford1939) rez <- analyze(x) print(rez) - - } \seealso{ https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM diff --git a/man/analyze.fa.Rd b/man/analyze.fa.Rd index da67d37..a260885 100644 --- a/man/analyze.fa.Rd +++ b/man/analyze.fa.Rd @@ -31,8 +31,6 @@ results <- analyze(x) print(results) summary(results) plot(results) - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/analyze.glm.Rd b/man/analyze.glm.Rd index 5c8fe7a..5bd18a4 100644 --- a/man/analyze.glm.Rd +++ b/man/analyze.glm.Rd @@ -23,12 +23,11 @@ Analyze glm objects. } \examples{ library(psycho) -fit <- glm(Sex ~ Adjusting, data=psycho::affective, family="binomial") +fit <- glm(Sex ~ Adjusting, data = psycho::affective, family = "binomial") results <- analyze(fit) summary(results) print(results) - } \references{ Nakagawa, S., & Schielzeth, H. (2013). A general and simple method for obtaining R2 from generalized linear mixed-effects models. Methods in Ecology and Evolution, 4(2), 133-142. diff --git a/man/analyze.glmerMod.Rd b/man/analyze.glmerMod.Rd index a542b0b..8f4d86b 100644 --- a/man/analyze.glmerMod.Rd +++ b/man/analyze.glmerMod.Rd @@ -27,14 +27,13 @@ Analyze glmerMod objects. library(psycho) library(lme4) -fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") +fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") results <- analyze(fit) summary(results) print(results) } - } \references{ Nakagawa, S., & Schielzeth, H. (2013). A general and simple method for obtaining R2 from generalized linear mixed-effects models. Methods in Ecology and Evolution, 4(2), 133-142. diff --git a/man/analyze.htest.Rd b/man/analyze.htest.Rd index 0bfd4af..04761cd 100644 --- a/man/analyze.htest.Rd +++ b/man/analyze.htest.Rd @@ -26,13 +26,12 @@ df <- psycho::affective x <- t.test(df$Tolerating, df$Adjusting) x <- t.test(df$Tolerating ~ df$Sex) -x <- t.test(df$Tolerating, mu=2) +x <- t.test(df$Tolerating, mu = 2) x <- cor.test(df$Tolerating, df$Adjusting) results <- analyze(x) summary(results) print(results) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/analyze.lavaan.Rd b/man/analyze.lavaan.Rd index 387e00a..6ea1a5a 100644 --- a/man/analyze.lavaan.Rd +++ b/man/analyze.lavaan.Rd @@ -25,15 +25,11 @@ Analyze lavaan (SEM or CFA) objects. library(psycho) library(lavaan) -model <- ' visual =~ x1 + x2 + x3 - textual =~ x4 + x5 + x6 - speed =~ x7 + x8 + x9 ' -x <- lavaan::cfa(model, data=HolzingerSwineford1939) +model <- " visual =~ x1 + x2 + x3\\ntextual =~ x4 + x5 + x6\\nspeed =~ x7 + x8 + x9 " +x <- lavaan::cfa(model, data = HolzingerSwineford1939) rez <- analyze(x) print(rez) - - } \seealso{ https://www.researchgate.net/post/Whats_the_standard_of_fit_indices_in_SEM diff --git a/man/analyze.lm.Rd b/man/analyze.lm.Rd index 3e79d84..6594fa9 100644 --- a/man/analyze.lm.Rd +++ b/man/analyze.lm.Rd @@ -23,13 +23,12 @@ Analyze lm objects. } \examples{ library(psycho) -fit <- lm(Sepal.Length ~ Sepal.Width, data=iris) -fit <- lm(Sepal.Length ~ Sepal.Width * Species, data=iris) +fit <- lm(Sepal.Length ~ Sepal.Width, data = iris) +fit <- lm(Sepal.Length ~ Sepal.Width * Species, data = iris) results <- analyze(fit) summary(results) print(results) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/analyze.lmerModLmerTest.Rd b/man/analyze.lmerModLmerTest.Rd index d8ee989..1609d7e 100644 --- a/man/analyze.lmerModLmerTest.Rd +++ b/man/analyze.lmerModLmerTest.Rd @@ -25,12 +25,11 @@ Analyze lmerModLmerTest objects. \examples{ library(psycho) library(lmerTest) -fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) +fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + (1 | Species), data = iris) results <- analyze(fit) summary(results) print(results) - } \references{ Nakagawa, S., & Schielzeth, H. (2013). A general and simple method for obtaining R2 from generalized linear mixed-effects models. Methods in Ecology and Evolution, 4(2), 133-142. diff --git a/man/analyze.principal.Rd b/man/analyze.principal.Rd index cedf2b2..c1b7f04 100644 --- a/man/analyze.principal.Rd +++ b/man/analyze.principal.Rd @@ -31,8 +31,6 @@ results <- analyze(x) print(results) summary(results) plot(results) - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/analyze.stanreg.Rd b/man/analyze.stanreg.Rd index f917a79..4acffa7 100644 --- a/man/analyze.stanreg.Rd +++ b/man/analyze.stanreg.Rd @@ -44,25 +44,27 @@ library(psycho) library(rstanarm) data <- attitude -fit <- rstanarm::stan_glm(rating ~ advance + privileges, data=data) +fit <- rstanarm::stan_glm(rating ~ advance + privileges, data = data) -results <- analyze(fit, effsize=TRUE) +results <- analyze(fit, effsize = TRUE) summary(results) print(results) plot(results) -fit <- rstanarm::stan_lmer(Sepal.Length ~ Sepal.Width + (1|Species), data=iris) +fit <- rstanarm::stan_lmer(Sepal.Length ~ Sepal.Width + (1 | Species), data = iris) results <- analyze(fit) summary(results) fit <- rstanarm::stan_glm(Sex ~ Adjusting, - data=psycho::affective, family="binomial") + data = psycho::affective, family = "binomial" +) results <- analyze(fit) summary(results) -fit <- rstanarm::stan_glmer(Sex ~ Adjusting + (1|Salary), - data=psycho::affective, family="binomial") +fit <- rstanarm::stan_glmer(Sex ~ Adjusting + (1 | Salary), + data = psycho::affective, family = "binomial" +) results <- analyze(fit) summary(results) } diff --git a/man/assess.Rd b/man/assess.Rd index a059255..68c0ceb 100644 --- a/man/assess.Rd +++ b/man/assess.Rd @@ -51,10 +51,9 @@ Compare a patient's score to a control group. Until relatively recently the standard way of testing for a difference between a case and controls was to convert the case’s score to a z score using the control sample mean and standard deviation (SD). If z was less than -1.645 (i.e., below 95% of the controls) then it was concluded that the case was significantly lower than controls. However, this method has serious disadvantages (Crawford and Garthwaite, 2012). } \examples{ -result <- assess(patient=124, mean=100, sd=15, n=100) +result <- assess(patient = 124, mean = 100, sd = 15, n = 100) print(result) plot(result) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/correlation.Rd b/man/correlation.Rd index 208c0cb..a5980f5 100644 --- a/man/correlation.Rd +++ b/man/correlation.Rd @@ -45,12 +45,13 @@ print(results) plot(results) # Partial correlations with correction -results <- psycho::correlation(df, type="partial", - method="spearman", - adjust="holm") +results <- psycho::correlation(df, + type = "partial", + method = "spearman", + adjust = "holm" +) print(results) plot(results) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/crawford.test.Rd b/man/crawford.test.Rd index ad5c867..717bd8d 100644 --- a/man/crawford.test.Rd +++ b/man/crawford.test.Rd @@ -49,13 +49,12 @@ The p value obtained when this test is used to test significance also simultaneo \examples{ library(psycho) -crawford.test(patient = 125, mean=100, sd=15, n=100) -plot(crawford.test(patient = 80, mean=100, sd=15, n=100)) +crawford.test(patient = 125, mean = 100, sd = 15, n = 100) +plot(crawford.test(patient = 80, mean = 100, sd = 15, n = 100)) crawford.test(patient = 10, controls = c(0, -2, 5, 2, 1, 3, -4, -2)) test <- crawford.test(patient = 7, controls = c(0, -2, 5, -6, 0, 3, -4, -2)) plot(test) - } \author{ Dominique Makowski diff --git a/man/crawford.test.freq.Rd b/man/crawford.test.freq.Rd index de42264..e20fcdb 100644 --- a/man/crawford.test.freq.Rd +++ b/man/crawford.test.freq.Rd @@ -23,7 +23,6 @@ library(psycho) crawford.test.freq(patient = 10, controls = c(0, -2, 5, 2, 1, 3, -4, -2)) crawford.test.freq(patient = 7, controls = c(0, -2, 5, 2, 1, 3, -4, -2)) - } \author{ Dan Mirman, Dominique Makowski diff --git a/man/crawford_dissociation.test.Rd b/man/crawford_dissociation.test.Rd index 1122e64..78f9418 100644 --- a/man/crawford_dissociation.test.Rd +++ b/man/crawford_dissociation.test.Rd @@ -34,7 +34,6 @@ controls_X <- c(100, 125, 89, 105, 109, 99) controls_Y <- c(7, 8, 9, 6, 7, 10) crawford_dissociation.test(case_X, case_Y, controls_X, controls_Y) - } \author{ Dominique Makowski diff --git a/man/create_intervals.Rd b/man/create_intervals.Rd index bf72b57..122e9fc 100644 --- a/man/create_intervals.Rd +++ b/man/create_intervals.Rd @@ -28,14 +28,12 @@ library(psycho) x <- rnorm(100, 0, 1) -create_intervals(x, n=4) -create_intervals(x, n=4, equal_range=FALSE) -create_intervals(x, length=1) - -create_intervals(x, n=4, labels="median") -create_intervals(x, n=4, labels=FALSE) - +create_intervals(x, n = 4) +create_intervals(x, n = 4, equal_range = FALSE) +create_intervals(x, length = 1) +create_intervals(x, n = 4, labels = "median") +create_intervals(x, n = 4, labels = FALSE) } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/dprime.Rd b/man/dprime.Rd index 87b179f..e567cd6 100644 --- a/man/dprime.Rd +++ b/man/dprime.Rd @@ -51,17 +51,19 @@ n_cr <- 7 indices <- psycho::dprime(n_hit, n_fa, n_miss, n_cr) -df <- data.frame(Participant = c("A", "B", "C"), - n_hit = c(1, 2, 5), - n_fa = c(6, 8, 1)) - -indices <- psycho::dprime(n_hit=df$n_hit, - n_fa=df$n_fa, - n_targets=10, - n_distractors=10, - adjusted=FALSE) - - +df <- data.frame( + Participant = c("A", "B", "C"), + n_hit = c(1, 2, 5), + n_fa = c(6, 8, 1) +) + +indices <- psycho::dprime( + n_hit = df$n_hit, + n_fa = df$n_fa, + n_targets = 10, + n_distractors = 10, + adjusted = FALSE +) } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/find_best_model.lavaan.Rd b/man/find_best_model.lavaan.Rd new file mode 100644 index 0000000..c3256c4 --- /dev/null +++ b/man/find_best_model.lavaan.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/find_best_model.lavaan.R +\name{find_best_model.lavaan} +\alias{find_best_model.lavaan} +\title{Returns all combinations of lavaan models with their indices of fit.} +\usage{ +\method{find_best_model}{lavaan}(fit, latent = "", samples = 1000, + verbose = FALSE, ...) +} +\arguments{ +\item{fit}{A lavaan object.} + +\item{latent}{Copy/paste the part related to latent variables loadings.} + +\item{samples}{Number of random draws.} + +\item{verbose}{Show progress.} + +\item{...}{Arguments passed to or from other methods.} +} +\value{ +list containing all combinations. +} +\description{ +Returns all combinations of lavaan models with their indices of fit. +} +\examples{ +library(psycho) +library(lavaan) + +model <- " visual =~ x1 + x2 + x3 +textual =~ x4 + x5 + x6 +speed =~ x7 + x8 + x9 +visual ~ textual +textual ~ speed" +fit <- lavaan::sem(model, data = HolzingerSwineford1939) + +models <- find_best_model(fit, latent = "visual =~ x1 + x2 + x3 +textual =~ x4 + x5 + x6 +speed =~ x7 + x8 + x9") +} +\author{ +\href{https://dominiquemakowski.github.io/}{Dominique Makowski} +} diff --git a/man/find_best_model.lmerModLmerTest.Rd b/man/find_best_model.lmerModLmerTest.Rd index 165477d..a70fbef 100644 --- a/man/find_best_model.lmerModLmerTest.Rd +++ b/man/find_best_model.lmerModLmerTest.Rd @@ -29,12 +29,11 @@ library(psycho) library(lmerTest) data <- standardize(iris) -fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + Petal.Length + (1|Species), data=data) +fit <- lmerTest::lmer(Sepal.Length ~ Sepal.Width + Petal.Length + (1 | Species), data = data) best <- find_best_model(fit) best_formula <- best$formula best$table - } } diff --git a/man/find_best_model.stanreg.Rd b/man/find_best_model.stanreg.Rd index e6f0788..3082aae 100644 --- a/man/find_best_model.stanreg.Rd +++ b/man/find_best_model.stanreg.Rd @@ -39,14 +39,14 @@ library(psycho) library(rstanarm) data <- standardize(attitude) -fit <- rstanarm::stan_glm(rating ~ advance + privileges, data=data) +fit <- rstanarm::stan_glm(rating ~ advance + privileges, data = data) best <- find_best_model(fit) best_formula <- best$formula best$table # To deactivate Kfold evaluation -best <- find_best_model(fit, K=0) +best <- find_best_model(fit, K = 0) } } diff --git a/man/find_combinations.formula.Rd b/man/find_combinations.formula.Rd index fab1726..5968a49 100644 --- a/man/find_combinations.formula.Rd +++ b/man/find_combinations.formula.Rd @@ -31,7 +31,6 @@ f <- as.formula("Y ~ A + B + C + D + (1|E)") f <- as.formula("Y ~ A + B + C + D + (1|E) + (1|F)") find_combinations(f) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/find_matching_string.Rd b/man/find_matching_string.Rd index c4f558c..1b2e4ad 100644 --- a/man/find_matching_string.Rd +++ b/man/find_matching_string.Rd @@ -24,7 +24,6 @@ Fuzzy string matching. \examples{ library(psycho) find_matching_string("Hwo rea ouy", c("How are you", "Not this word", "Nice to meet you")) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/find_random_effects.Rd b/man/find_random_effects.Rd index 47d7fe8..2fb6fa0 100644 --- a/man/find_random_effects.Rd +++ b/man/find_random_effects.Rd @@ -15,7 +15,6 @@ Find random effects in formula. \examples{ library(psycho) find_random_effects("Y ~ X + (1|Group)") - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/find_season.Rd b/man/find_season.Rd index eeb2af6..4241194 100644 --- a/man/find_season.Rd +++ b/man/find_season.Rd @@ -29,7 +29,6 @@ library(psycho) dates <- c("2012-02-15", "2017-05-15", "2009-08-15", "1912-11-15") find_season(dates) - } \seealso{ https://stackoverflow.com/questions/9500114/find-which-season-a-particular-date-belongs-to diff --git a/man/format_formula.Rd b/man/format_formula.Rd index cbb9408..b01343c 100644 --- a/man/format_formula.Rd +++ b/man/format_formula.Rd @@ -18,12 +18,10 @@ Clean and format formula. library(psycho) library(lme4) -fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") -fit <- lm(hp ~ wt, data=mtcars) +fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") +fit <- lm(hp ~ wt, data = mtcars) format_formula(get_formula(fit)) - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/get_R2.glm.Rd b/man/get_R2.glm.Rd index f43636e..24f950b 100644 --- a/man/get_R2.glm.Rd +++ b/man/get_R2.glm.Rd @@ -20,11 +20,10 @@ Pseudo-R-squared for Logistic Models. \dontrun{ library(psycho) -fit <- glm(vs ~ wt, data=mtcars, family="binomial") -fit <- glm(Sex ~ Adjusting, data=psycho::affective, family="binomial") +fit <- glm(vs ~ wt, data = mtcars, family = "binomial") +fit <- glm(Sex ~ Adjusting, data = psycho::affective, family = "binomial") get_R2(fit) - } } diff --git a/man/get_R2.lm.Rd b/man/get_R2.lm.Rd index 51d53b7..05231cf 100644 --- a/man/get_R2.lm.Rd +++ b/man/get_R2.lm.Rd @@ -18,10 +18,9 @@ R2 and adjusted R2 for Linear Models. \dontrun{ library(psycho) -fit <- lm(Tolerating ~ Adjusting, data=psycho::affective) +fit <- lm(Tolerating ~ Adjusting, data = psycho::affective) get_R2(fit) - } } diff --git a/man/get_R2.merMod.Rd b/man/get_R2.merMod.Rd index 7cd0d7e..9b7c2b3 100644 --- a/man/get_R2.merMod.Rd +++ b/man/get_R2.merMod.Rd @@ -18,11 +18,12 @@ R2 and adjusted R2 for GLMMs. \dontrun{ library(psycho) -fit <- lmerTest::lmer(Tolerating ~ Adjusting + (1|Sex), data=psycho::affective) -fit <- lme4::glmer(Sex ~ Adjusting + (1|Salary), data=na.omit(psycho::affective), family="binomial") +fit <- lmerTest::lmer(Tolerating ~ Adjusting + (1 | Sex), + data = psycho::affective) +fit <- lme4::glmer(Sex ~ Adjusting + (1 | Salary), + data = na.omit(psycho::affective), family = "binomial") get_R2(fit) - } } diff --git a/man/get_R2.stanreg.Rd b/man/get_R2.stanreg.Rd index e9740ca..c4361b7 100644 --- a/man/get_R2.stanreg.Rd +++ b/man/get_R2.stanreg.Rd @@ -21,10 +21,9 @@ Computes R2 and \link[=R2_LOO_Adjusted]{LOO-adjusted R2}. library(psycho) library(rstanarm) -fit <- rstanarm::stan_glm(Adjusting ~ Tolerating, data=psycho::affective) +fit <- rstanarm::stan_glm(Adjusting ~ Tolerating, data = psycho::affective) get_R2(fit) - } } diff --git a/man/get_cfa_model.Rd b/man/get_cfa_model.Rd index 2ce6e14..83ef8de 100644 --- a/man/get_cfa_model.Rd +++ b/man/get_cfa_model.Rd @@ -20,11 +20,10 @@ library(psycho) x <- psych::fa(psych::Thurstone.33, 2) loadings <- format_loadings(x)$loadings -get_cfa_model(loadings, treshold="max") -get_cfa_model(loadings, treshold=0.1) +get_cfa_model(loadings, treshold = "max") +get_cfa_model(loadings, treshold = 0.1) } - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/get_contrasts.Rd b/man/get_contrasts.Rd index 19a9fed..768e072 100644 --- a/man/get_contrasts.Rd +++ b/man/get_contrasts.Rd @@ -30,18 +30,17 @@ library(psycho) require(lmerTest) require(rstanarm) -fit <- lm(Adjusting ~ Birth_Season * Salary, data=affective) +fit <- lm(Adjusting ~ Birth_Season * Salary, data = affective) get_contrasts(fit) -fit <- lm(Adjusting ~ Birth_Season * Salary, data=affective) -get_contrasts(fit, adjust="bonf") +fit <- lm(Adjusting ~ Birth_Season * Salary, data = affective) +get_contrasts(fit, adjust = "bonf") -fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1|Salary), data=affective) -get_contrasts(fit, formula="Birth_Season") - -fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data=affective) -get_contrasts(fit, formula="Birth_Season", ROPE_bounds=c(-0.1, 0.1)) +fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1 | Salary), data = affective) +get_contrasts(fit, formula = "Birth_Season") +fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data = affective) +get_contrasts(fit, formula = "Birth_Season", ROPE_bounds = c(-0.1, 0.1)) } } \author{ diff --git a/man/get_data.Rd b/man/get_data.Rd index 66f3d53..1f2d42e 100644 --- a/man/get_data.Rd +++ b/man/get_data.Rd @@ -20,18 +20,19 @@ library(tidyverse) library(psycho) df <- mtcars \%>\% - mutate(cyl = as.factor(cyl), - gear = as.factor(gear)) + mutate( + cyl = as.factor(cyl), + gear = as.factor(gear) + ) -fit <- lm(wt ~ mpg , data=df) -fit <- lm(wt ~ cyl, data=df) -fit <- lm(wt ~ mpg * cyl, data=df) -fit <- lm(wt ~ cyl * gear, data=df) -fit <- lmerTest::lmer(wt ~ mpg * gear + (1|cyl), data=df) -fit <- rstanarm::stan_lmer(wt ~ mpg * gear + (1|cyl), data=df) +fit <- lm(wt ~ mpg, data = df) +fit <- lm(wt ~ cyl, data = df) +fit <- lm(wt ~ mpg * cyl, data = df) +fit <- lm(wt ~ cyl * gear, data = df) +fit <- lmerTest::lmer(wt ~ mpg * gear + (1 | cyl), data = df) +fit <- rstanarm::stan_lmer(wt ~ mpg * gear + (1 | cyl), data = df) get_data(fit) - } } diff --git a/man/get_formula.Rd b/man/get_formula.Rd index bf5f617..882a1a6 100644 --- a/man/get_formula.Rd +++ b/man/get_formula.Rd @@ -25,12 +25,10 @@ Get formula of models. Implemented for: library(psycho) library(lme4) -fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") -fit <- lm(hp ~ wt, data=mtcars) +fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") +fit <- lm(hp ~ wt, data = mtcars) get_formula(fit) - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/get_graph.psychobject_correlation.Rd b/man/get_graph.psychobject_correlation.Rd index 68d7b70..3f83cb9 100644 --- a/man/get_graph.psychobject_correlation.Rd +++ b/man/get_graph.psychobject_correlation.Rd @@ -4,10 +4,10 @@ \alias{get_graph.psychobject_correlation} \title{Get graph data from correlation.} \usage{ -\method{get_graph}{psychobject_correlation}(cor, ...) +\method{get_graph}{psychobject_correlation}(fit, ...) } \arguments{ -\item{cor}{Object from psycho::correlation.} +\item{fit}{Object from psycho::correlation.} \item{...}{Arguments passed to or from other methods.} } diff --git a/man/get_info.Rd b/man/get_info.Rd index 6062256..249d731 100644 --- a/man/get_info.Rd +++ b/man/get_info.Rd @@ -21,12 +21,10 @@ Get information about models. library(psycho) library(lme4) -fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") +fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") info <- get_info(fit) info - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/get_info.lm.Rd b/man/get_info.lm.Rd index 38b0de0..5994fda 100644 --- a/man/get_info.lm.Rd +++ b/man/get_info.lm.Rd @@ -21,11 +21,12 @@ Get information about models. library(psycho) library(lme4) -fit <- lm(vs ~ wt, data=mtcars, family="binomial") +fit <- lm(vs ~ wt, data = mtcars, family = "binomial") info <- get_info(fit) info +# } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/get_info.lmerModLmerTest.Rd b/man/get_info.lmerModLmerTest.Rd index 3c91485..9ef22d4 100644 --- a/man/get_info.lmerModLmerTest.Rd +++ b/man/get_info.lmerModLmerTest.Rd @@ -21,11 +21,12 @@ Get information about models. library(psycho) library(lme4) -fit <- lme4::glmer(vs ~ wt + (1|gear), data=mtcars, family="binomial") +fit <- lme4::glmer(vs ~ wt + (1 | gear), data = mtcars, family = "binomial") info <- get_info(fit) info +# } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/get_loadings_max.Rd b/man/get_loadings_max.Rd index 50c13b6..3073720 100644 --- a/man/get_loadings_max.Rd +++ b/man/get_loadings_max.Rd @@ -20,7 +20,6 @@ x <- psych::fa(psych::Thurstone.33, 2) get_loadings_max(format_loadings(x)$loadings) } - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/get_means.Rd b/man/get_means.Rd index 62ac048..7e6b279 100644 --- a/man/get_means.Rd +++ b/man/get_means.Rd @@ -29,15 +29,14 @@ require(lmerTest) require(rstanarm) -fit <- glm(Sex ~ Birth_Season, data=affective, family="binomial") +fit <- glm(Sex ~ Birth_Season, data = affective, family = "binomial") get_means(fit) -fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1|Salary), data=affective) -get_means(fit, formula="Birth_Season") - -fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data=affective) -get_means(fit, formula="Birth_Season") +fit <- lmerTest::lmer(Adjusting ~ Birth_Season * Salary + (1 | Salary), data = affective) +get_means(fit, formula = "Birth_Season") +fit <- rstanarm::stan_glm(Adjusting ~ Birth_Season, data = affective) +get_means(fit, formula = "Birth_Season") } } \author{ diff --git a/man/get_predicted.glm.Rd b/man/get_predicted.glm.Rd index 6eb181e..ba0386f 100644 --- a/man/get_predicted.glm.Rd +++ b/man/get_predicted.glm.Rd @@ -29,17 +29,19 @@ Compute predicted from a lm model. library(psycho) library(ggplot2) -fit <- glm(Sex ~ Adjusting, data=affective, family="binomial") +fit <- glm(Sex ~ Adjusting, data = affective, family = "binomial") refgrid <- psycho::refdata(affective, "Adjusting") -predicted <- get_predicted(fit, newdata=refgrid) +predicted <- get_predicted(fit, newdata = refgrid) -ggplot(predicted, aes(x=Adjusting, y=Sex_Predicted)) + +ggplot(predicted, aes(x = Adjusting, y = Sex_Predicted)) + geom_line() + - geom_ribbon(aes(ymin=Sex_CI_2.5, - ymax=Sex_CI_97.5), - alpha=0.1) - + geom_ribbon(aes( + ymin = Sex_CI_2.5, + ymax = Sex_CI_97.5 + ), + alpha = 0.1 + ) } } \author{ diff --git a/man/get_predicted.lm.Rd b/man/get_predicted.lm.Rd index c1d50d2..afc8fab 100644 --- a/man/get_predicted.lm.Rd +++ b/man/get_predicted.lm.Rd @@ -26,18 +26,19 @@ Compute predicted from a lm model. library(psycho) library(ggplot2) -fit <- lm(Tolerating ~ Adjusting, data=affective) +fit <- lm(Tolerating ~ Adjusting, data = affective) refgrid <- psycho::refdata(affective, "Adjusting") -predicted <- get_predicted(fit, newdata=refgrid) +predicted <- get_predicted(fit, newdata = refgrid) -ggplot(predicted, aes(x=Adjusting, y=Tolerating_Predicted)) + +ggplot(predicted, aes(x = Adjusting, y = Tolerating_Predicted)) + geom_line() + - geom_ribbon(aes(ymin=Tolerating_CI_2.5, - ymax=Tolerating_CI_97.5), - alpha=0.1) - - + geom_ribbon(aes( + ymin = Tolerating_CI_2.5, + ymax = Tolerating_CI_97.5 + ), + alpha = 0.1 + ) } } \author{ diff --git a/man/get_predicted.merMod.Rd b/man/get_predicted.merMod.Rd index 1485d32..c828ccf 100644 --- a/man/get_predicted.merMod.Rd +++ b/man/get_predicted.merMod.Rd @@ -38,40 +38,45 @@ Compute predicted from a lm model. library(psycho) library(ggplot2) -fit <- lmerTest::lmer(Tolerating ~ Adjusting + (1|Salary), data=affective) +fit <- lmerTest::lmer(Tolerating ~ Adjusting + (1 | Salary), data = affective) refgrid <- psycho::refdata(affective, "Adjusting") -predicted <- get_predicted(fit, newdata=refgrid) +predicted <- get_predicted(fit, newdata = refgrid) -ggplot(predicted, aes(x=Adjusting, y=Tolerating_Predicted)) + +ggplot(predicted, aes(x = Adjusting, y = Tolerating_Predicted)) + geom_line() -predicted <- get_predicted(fit, newdata=refgrid, prob=0.95, iter=100) # Takes a long time +predicted <- get_predicted(fit, newdata = refgrid, prob = 0.95, iter = 100) # Takes a long time -ggplot(predicted, aes(x=Adjusting, y=Tolerating_Predicted)) + +ggplot(predicted, aes(x = Adjusting, y = Tolerating_Predicted)) + geom_line() + - geom_ribbon(aes(ymin=Tolerating_CI_2.5, - ymax=Tolerating_CI_97.5), - alpha=0.1) + geom_ribbon(aes( + ymin = Tolerating_CI_2.5, + ymax = Tolerating_CI_97.5 + ), + alpha = 0.1 + ) -fit <- lme4::glmer(Sex ~ Adjusting + (1|Salary), data=affective, family="binomial") +fit <- lme4::glmer(Sex ~ Adjusting + (1 | Salary), data = affective, family = "binomial") refgrid <- psycho::refdata(affective, "Adjusting") -predicted <- get_predicted(fit, newdata=refgrid) +predicted <- get_predicted(fit, newdata = refgrid) -ggplot(predicted, aes(x=Adjusting, y=Sex_Predicted)) + +ggplot(predicted, aes(x = Adjusting, y = Sex_Predicted)) + geom_line() -predicted <- get_predicted(fit, newdata=refgrid, prob=0.95, iter=100) # Takes a long time +predicted <- get_predicted(fit, newdata = refgrid, prob = 0.95, iter = 100) # Takes a long time -ggplot(predicted, aes(x=Adjusting, y=Sex_Predicted)) + +ggplot(predicted, aes(x = Adjusting, y = Sex_Predicted)) + geom_line() + - geom_ribbon(aes(ymin=Sex_CI_2.5, - ymax=Sex_CI_97.5), - alpha=0.1) - + geom_ribbon(aes( + ymin = Sex_CI_2.5, + ymax = Sex_CI_97.5 + ), + alpha = 0.1 + ) } } \author{ diff --git a/man/get_predicted.stanreg.Rd b/man/get_predicted.stanreg.Rd index fc2d951..27ee5ce 100644 --- a/man/get_predicted.stanreg.Rd +++ b/man/get_predicted.stanreg.Rd @@ -44,28 +44,33 @@ library(psycho) library(ggplot2) require(rstanarm) -fit <- rstanarm::stan_glm(Tolerating ~ Adjusting, data=affective) +fit <- rstanarm::stan_glm(Tolerating ~ Adjusting, data = affective) refgrid <- psycho::refdata(affective, "Adjusting") -predicted <- get_predicted(fit, newdata=refgrid) +predicted <- get_predicted(fit, newdata = refgrid) -ggplot(predicted, aes(x=Adjusting, y=Tolerating_Median)) + +ggplot(predicted, aes(x = Adjusting, y = Tolerating_Median)) + geom_line() + - geom_ribbon(aes(ymin=Tolerating_CI_5, - ymax=Tolerating_CI_95), - alpha=0.1) + geom_ribbon(aes( + ymin = Tolerating_CI_5, + ymax = Tolerating_CI_95 + ), + alpha = 0.1 + ) -fit <- rstanarm::stan_glm(Sex ~ Adjusting, data=affective, family="binomial") +fit <- rstanarm::stan_glm(Sex ~ Adjusting, data = affective, family = "binomial") refgrid <- psycho::refdata(affective, "Adjusting") -predicted <- get_predicted(fit, newdata=refgrid) +predicted <- get_predicted(fit, newdata = refgrid) -ggplot(predicted, aes(x=Adjusting, y=Sex_Median)) + +ggplot(predicted, aes(x = Adjusting, y = Sex_Median)) + geom_line() + - geom_ribbon(aes(ymin=Sex_CI_5, - ymax=Sex_CI_95), - alpha=0.1) - + geom_ribbon(aes( + ymin = Sex_CI_5, + ymax = Sex_CI_95 + ), + alpha = 0.1 + ) } } \author{ diff --git a/man/golden.Rd b/man/golden.Rd index 0f8b000..c4fa349 100644 --- a/man/golden.Rd +++ b/man/golden.Rd @@ -17,7 +17,6 @@ library(psycho) golden() golden(8) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/hdi.Rd b/man/hdi.Rd index 1944bfd..9517ea1 100644 --- a/man/hdi.Rd +++ b/man/hdi.Rd @@ -25,7 +25,6 @@ summary(HDI_values) x <- matrix(rexp(200), 100) HDI_values <- HDI(x) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/interpret_R2.Rd b/man/interpret_R2.Rd index 1052fd6..1ad061c 100644 --- a/man/interpret_R2.Rd +++ b/man/interpret_R2.Rd @@ -16,9 +16,8 @@ Interpret R2 with a set of rules. } \examples{ library(psycho) -interpret_R2(x=0.42) -interpret_R2(x=c(0.42, 0.2, 0.9, 0)) - +interpret_R2(x = 0.42) +interpret_R2(x = c(0.42, 0.2, 0.9, 0)) } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/interpret_R2_posterior.Rd b/man/interpret_R2_posterior.Rd index b051bf1..4e80418 100644 --- a/man/interpret_R2_posterior.Rd +++ b/man/interpret_R2_posterior.Rd @@ -18,7 +18,6 @@ Interpret R2 with a set of rules. library(psycho) posterior <- rnorm(1000, 0.4, 0.1) interpret_R2_posterior(posterior) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/interpret_RMSEA.Rd b/man/interpret_RMSEA.Rd index f37a88f..ff69440 100644 --- a/man/interpret_RMSEA.Rd +++ b/man/interpret_RMSEA.Rd @@ -17,7 +17,6 @@ Interpret RMSEA with a set of rules. \examples{ library(psycho) interpret_RMSEA(0.04) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/interpret_bf.Rd b/man/interpret_bf.Rd index 0cc76f2..126f554 100644 --- a/man/interpret_bf.Rd +++ b/man/interpret_bf.Rd @@ -20,8 +20,7 @@ Return the interpretation of a Bayes Factor. } \examples{ library(psycho) -interpret_bf(x=10) - +interpret_bf(x = 10) } \references{ \itemize{ diff --git a/man/interpret_d.Rd b/man/interpret_d.Rd index b02ff8e..4c8365c 100644 --- a/man/interpret_d.Rd +++ b/man/interpret_d.Rd @@ -20,7 +20,6 @@ Interpret d with a set of rules. library(psycho) interpret_d(-0.42) interpret_d(-0.62) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/interpret_d_posterior.Rd b/man/interpret_d_posterior.Rd index 52a3b1e..b750d49 100644 --- a/man/interpret_d_posterior.Rd +++ b/man/interpret_d_posterior.Rd @@ -19,7 +19,6 @@ library(psycho) posterior <- rnorm(1000, 0.6, 0.05) interpret_d_posterior(posterior) interpret_d_posterior(rnorm(1000, 0.1, 1)) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/interpret_lavaan.blavaan.Rd b/man/interpret_lavaan.blavaan.Rd new file mode 100644 index 0000000..3d72c76 --- /dev/null +++ b/man/interpret_lavaan.blavaan.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interpret_lavaan.R +\name{interpret_lavaan.blavaan} +\alias{interpret_lavaan.blavaan} +\title{Interpret fit measures of blavaan objects} +\usage{ +\method{interpret_lavaan}{blavaan}(fit, indices = c("BIC", "DIC", "WAIC", + "LOOIC"), ...) +} +\arguments{ +\item{fit}{lavaan or blavaan object.} + +\item{indices}{Vector of strings indicating which indices to report. Only works for bayesian objects for now.} + +\item{...}{Arguments passed to or from other methods.} +} +\description{ +Interpret fit measures of blavaan objects +} diff --git a/man/interpret_lavaan.lavaan.Rd b/man/interpret_lavaan.lavaan.Rd new file mode 100644 index 0000000..2df1185 --- /dev/null +++ b/man/interpret_lavaan.lavaan.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/interpret_lavaan.R +\name{interpret_lavaan.lavaan} +\alias{interpret_lavaan.lavaan} +\title{Interpret fit measures of lavaan objects} +\usage{ +\method{interpret_lavaan}{lavaan}(fit, ...) +} +\arguments{ +\item{fit}{lavaan or blavaan object.} + +\item{...}{Arguments passed to or from other methods.} +} +\description{ +Interpret fit measures of lavaan objects +} diff --git a/man/interpret_odds.Rd b/man/interpret_odds.Rd index 24fe6bd..09de8b7 100644 --- a/man/interpret_odds.Rd +++ b/man/interpret_odds.Rd @@ -20,8 +20,7 @@ Interpret odds with a set of rules. } \examples{ library(psycho) -interpret_odds(x=2) - +interpret_odds(x = 2) } \references{ \itemize{ diff --git a/man/interpret_odds_posterior.Rd b/man/interpret_odds_posterior.Rd index d31fe46..3b3a405 100644 --- a/man/interpret_odds_posterior.Rd +++ b/man/interpret_odds_posterior.Rd @@ -22,7 +22,6 @@ posterior <- rnorm(1000, 0.6, 0.05) interpret_odds_posterior(posterior) interpret_odds_posterior(rnorm(1000, 0.1, 1)) interpret_odds_posterior(rnorm(1000, 3, 1.5)) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/interpret_omega_sq.Rd b/man/interpret_omega_sq.Rd index 7595a74..579ccf6 100644 --- a/man/interpret_omega_sq.Rd +++ b/man/interpret_omega_sq.Rd @@ -16,8 +16,7 @@ Return the interpretation of Omegas Squared. } \examples{ library(psycho) -interpret_omega_sq(x=0.05) - +interpret_omega_sq(x = 0.05) } \references{ \itemize{ diff --git a/man/interpret_r.Rd b/man/interpret_r.Rd index 1c54929..c8d1b05 100644 --- a/man/interpret_r.Rd +++ b/man/interpret_r.Rd @@ -22,7 +22,6 @@ Interpret r with a set of rules. \examples{ library(psycho) interpret_r(-0.42) - } \seealso{ Page 88 of APA's 6th Edition diff --git a/man/interpret_r_posterior.Rd b/man/interpret_r_posterior.Rd index 0cee9e6..a66b884 100644 --- a/man/interpret_r_posterior.Rd +++ b/man/interpret_r_posterior.Rd @@ -18,7 +18,6 @@ Interpret r with a set of rules. library(psycho) posterior <- rnorm(1000, 0.5, 0.5) interpret_r_posterior(posterior) - } \seealso{ Page 88 of APA's 6th Edition diff --git a/man/is.standardized.Rd b/man/is.standardized.Rd index ca567f0..48adfcc 100644 --- a/man/is.standardized.Rd +++ b/man/is.standardized.Rd @@ -25,7 +25,6 @@ is.standardized(df) dfZ <- psycho::standardize(df) is.standardized(dfZ) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/mellenbergh.test.Rd b/man/mellenbergh.test.Rd index dd05c00..20c83c7 100644 --- a/man/mellenbergh.test.Rd +++ b/man/mellenbergh.test.Rd @@ -24,7 +24,6 @@ library(psycho) mellenbergh.test(t0 = 4, t1 = 12, controls = c(0, -2, 5, 2, 1, 3, -4, -2)) mellenbergh.test(t0 = 8, t1 = 2, controls = 2.6) - } \author{ Dominique Makowski diff --git a/man/model_to_priors.Rd b/man/model_to_priors.Rd index 8136f41..851901b 100644 --- a/man/model_to_priors.Rd +++ b/man/model_to_priors.Rd @@ -19,22 +19,24 @@ Convert a Bayesian model's results to priors. library(rstanarm) library(psycho) -fit <- stan_glm(Sepal.Length ~ Petal.Width, data=iris) +fit <- stan_glm(Sepal.Length ~ Petal.Width, data = iris) priors <- model_to_priors(fit) -update(fit, prior=priors$prior) +update(fit, prior = priors$prior) -fit <- stan_glmer(Subjective_Valence ~ Emotion_Condition + (1|Participant_ID), data=psycho::emotion) +fit <- stan_glmer(Subjective_Valence ~ Emotion_Condition + (1 | Participant_ID), + data = psycho::emotion) priors <- model_to_priors(fit) fit1 <- stan_glm(Subjective_Valence ~ Emotion_Condition, - data=filter(psycho::emotion, Participant_ID == "1S")) + data = filter(psycho::emotion, Participant_ID == "1S") +) fit2 <- stan_glm(Subjective_Valence ~ Emotion_Condition, - data=filter(psycho::emotion, Participant_ID == "1S"), - prior=priors$prior, prior_intercept=priors$prior_intercept) + data = filter(psycho::emotion, Participant_ID == "1S"), + prior = priors$prior, prior_intercept = priors$prior_intercept +) } - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/mpe.Rd b/man/mpe.Rd index e97e10a..46855ed 100644 --- a/man/mpe.Rd +++ b/man/mpe.Rd @@ -19,13 +19,11 @@ Compute the Maximum Probability of Effect (MPE), i.e., the proportion of posteri library(psycho) library(rstanarm) -fit <- rstanarm::stan_glm(rating ~ advance, data=attitude) +fit <- rstanarm::stan_glm(rating ~ advance, data = attitude) posterior <- psycho::analyze(fit)$values$effects$advance$posterior mpe <- psycho::mpe(posterior) print(mpe$MPE) print(mpe$values) - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/n_factors.Rd b/man/n_factors.Rd index 2ee0734..8edefdd 100644 --- a/man/n_factors.Rd +++ b/man/n_factors.Rd @@ -32,7 +32,6 @@ plot(results) # See details on methods psycho::values(results)$methods - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/odds_to_d.Rd b/man/odds_to_d.Rd index abd29d5..f203f54 100644 --- a/man/odds_to_d.Rd +++ b/man/odds_to_d.Rd @@ -16,8 +16,7 @@ odds_to_d(x, log = TRUE) } \examples{ library(psycho) -odds_to_d(x=2) - +odds_to_d(x = 2) } \references{ \itemize{ diff --git a/man/odds_to_probs.Rd b/man/odds_to_probs.Rd index 87c0b42..6100cab 100644 --- a/man/odds_to_probs.Rd +++ b/man/odds_to_probs.Rd @@ -23,8 +23,6 @@ Convert (log)odds to probabilies. \examples{ library(psycho) odds_to_probs(-1.45) - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/omega_sq.Rd b/man/omega_sq.Rd index e262976..a7fac9f 100644 --- a/man/omega_sq.Rd +++ b/man/omega_sq.Rd @@ -26,7 +26,6 @@ x <- aov(df$Tolerating ~ df$Salary) x <- aov(df$Tolerating ~ df$Salary * df$Sex) omega_sq(x) - } \seealso{ http://stats.stackexchange.com/a/126520 diff --git a/man/overlap.Rd b/man/overlap.Rd index a189280..2be189f 100644 --- a/man/overlap.Rd +++ b/man/overlap.Rd @@ -22,7 +22,6 @@ library(psycho) x <- rnorm(100, 1, 0.5) y <- rnorm(100, 0, 1) overlap(x, y) - } \author{ S. Venne diff --git a/man/percentile.Rd b/man/percentile.Rd index 9b2cbd1..6dafbdc 100644 --- a/man/percentile.Rd +++ b/man/percentile.Rd @@ -15,7 +15,6 @@ Transform z score to percentile. \examples{ library(psycho) percentile(-1.96) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/percentile_to_z.Rd b/man/percentile_to_z.Rd index 5ee132e..39e779a 100644 --- a/man/percentile_to_z.Rd +++ b/man/percentile_to_z.Rd @@ -15,7 +15,6 @@ Transform a percentile to a z score. \examples{ library(psycho) percentile_to_z(95) - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/plot_loadings.Rd b/man/plot_loadings.Rd index d9a0392..fec9e72 100644 --- a/man/plot_loadings.Rd +++ b/man/plot_loadings.Rd @@ -20,7 +20,6 @@ x <- psych::fa(psych::Thurstone.33, 2) plot_loadings(format_loadings(x)$loadings) } - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/power_analysis.Rd b/man/power_analysis.Rd index 8e13897..6b7b748 100644 --- a/man/power_analysis.Rd +++ b/man/power_analysis.Rd @@ -44,17 +44,19 @@ Compute the n models based on n sampling of data. library(dplyr) library(psycho) -fit <- lm(Sepal.Length ~ Sepal.Width, data=iris) +fit <- lm(Sepal.Length ~ Sepal.Width, data = iris) -results <- power_analysis(fit, n_max=300, n_min=100, step=5, n_batch=20) +results <- power_analysis(fit, n_max = 300, n_min = 100, step = 5, n_batch = 20) results \%>\% - filter(Variable=="Sepal.Width") \%>\% + filter(Variable == "Sepal.Width") \%>\% select(n, p) \%>\% group_by(n) \%>\% - summarise(p_median = median(p), - p_mad = mad(p)) - } + summarise( + p_median = median(p), + p_mad = mad(p) + ) +} } \author{ diff --git a/man/probs_to_odds.Rd b/man/probs_to_odds.Rd index b2507f2..47e6506 100644 --- a/man/probs_to_odds.Rd +++ b/man/probs_to_odds.Rd @@ -17,8 +17,6 @@ Convert probabilities to (log)odds. \examples{ library(psycho) probs_to_odds(0.75) - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/refdata.Rd b/man/refdata.Rd index 64795d3..e7e9ee9 100644 --- a/man/refdata.Rd +++ b/man/refdata.Rd @@ -5,7 +5,7 @@ \title{Create a reference grid.} \usage{ refdata(df, target = "all", length.out = 10, factors = "reference", - numerics = "mean") + numerics = "mean", na.rm = TRUE) } \arguments{ \item{df}{The dataframe.} @@ -17,6 +17,8 @@ refdata(df, target = "all", length.out = 10, factors = "reference", \item{factors}{Type of summary for factors. Can be "combination" or "reference".} \item{numerics}{Type of summary for numerics Can be "combination", any function ("mean", "median", ...) or a value.} + +\item{na.rm}{Remove NaNs.} } \description{ Create a reference grid. @@ -25,11 +27,10 @@ Create a reference grid. library(psycho) df <- psycho::affective -newdata <- refdata(df, target="Sex") -newdata <- refdata(df, target="Sex", factors="combinations") -newdata <- refdata(df, target=c("Sex", "Salary", "Tolerating"), length.out=3) -newdata <- refdata(df, target=c("Sex", "Salary", "Tolerating"), numerics=0) - +newdata <- refdata(df, target = "Sex") +newdata <- refdata(df, target = "Sex", factors = "combinations") +newdata <- refdata(df, target = c("Sex", "Salary", "Tolerating"), length.out = 3) +newdata <- refdata(df, target = c("Sex", "Salary", "Tolerating"), numerics = 0) } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/reorder_matrix.Rd b/man/reorder_matrix.Rd index 0a1c819..b628078 100644 --- a/man/reorder_matrix.Rd +++ b/man/reorder_matrix.Rd @@ -20,5 +20,4 @@ library(psycho) r <- correlation(iris) r <- r$values$r r <- reorder_matrix(r) - } diff --git a/man/rnorm_perfect.Rd b/man/rnorm_perfect.Rd index a8283aa..3b646c7 100644 --- a/man/rnorm_perfect.Rd +++ b/man/rnorm_perfect.Rd @@ -24,8 +24,6 @@ Generates a sample of size n with a near-perfect normal distribution. library(psycho) x <- rnorm_perfect(10) plot(density(x)) - - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/rope.Rd b/man/rope.Rd index 8024c42..983095c 100644 --- a/man/rope.Rd +++ b/man/rope.Rd @@ -27,7 +27,6 @@ library(psycho) posterior <- rnorm(1000, 0, 0.01) results <- rope(posterior) results$decision - } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/simulate_data_regression.Rd b/man/simulate_data_regression.Rd index 1580b26..46567f0 100644 --- a/man/simulate_data_regression.Rd +++ b/man/simulate_data_regression.Rd @@ -22,11 +22,10 @@ See https://stats.stackexchange.com/questions/59062/multiple-linear-regression-s \examples{ library(psycho) -data <- simulate_data_regression(coefs=c(0.1, 0.8), sample=50, error=0) -fit <- lm(y ~ ., data=data) +data <- simulate_data_regression(coefs = c(0.1, 0.8), sample = 50, error = 0) +fit <- lm(y ~ ., data = data) coef(fit) analyze(fit) - } \author{ TPArrow diff --git a/man/standardize.data.frame.Rd b/man/standardize.data.frame.Rd index 6693465..7a6cf55 100644 --- a/man/standardize.data.frame.Rd +++ b/man/standardize.data.frame.Rd @@ -29,19 +29,19 @@ Selects numeric variables and standardize (Z-score, "normalize") them. \examples{ \dontrun{ df <- data.frame( - Participant = as.factor(rep(1:25,each=4)), + Participant = as.factor(rep(1:25, each = 4)), Condition = base::rep_len(c("A", "B", "C", "D"), 100), V1 = rnorm(100, 30, .2), V2 = runif(100, 3, 5), V3 = rnorm(100, 100, 10) - ) +) dfZ <- standardize(df) -dfZ <- standardize(df, except="V3") -dfZ <- standardize(df, except=c("V1", "V2")) -dfZ <- standardize(df, subset="V3") -dfZ <- standardize(df, subset=c("V1", "V2")) -dfZ <- standardize(df, normalize=TRUE) +dfZ <- standardize(df, except = "V3") +dfZ <- standardize(df, except = c("V1", "V2")) +dfZ <- standardize(df, subset = "V3") +dfZ <- standardize(df, subset = c("V1", "V2")) +dfZ <- standardize(df, normalize = TRUE) # Respects grouping dfZ <- df \%>\% diff --git a/man/standardize.glm.Rd b/man/standardize.glm.Rd index 74f1375..ccc70ac 100644 --- a/man/standardize.glm.Rd +++ b/man/standardize.glm.Rd @@ -19,11 +19,10 @@ Compute standardized coefficients. \examples{ \dontrun{ library(psycho) -fit <- glm(Sex ~ Adjusting, data=psycho::affective, family="binomial") -fit <- lme4::glmer(Sex ~ Adjusting + (1|Sex), data=psycho::affective, family="binomial") +fit <- glm(Sex ~ Adjusting, data = psycho::affective, family = "binomial") +fit <- lme4::glmer(Sex ~ Adjusting + (1 | Sex), data = psycho::affective, family = "binomial") standardize(fit) - } } diff --git a/man/standardize.lm.Rd b/man/standardize.lm.Rd index a4f8428..c9efc7c 100644 --- a/man/standardize.lm.Rd +++ b/man/standardize.lm.Rd @@ -28,12 +28,11 @@ library(psycho) df <- mtcars \%>\% mutate(cyl = as.factor(cyl)) -fit <- lm(wt ~ mpg * cyl, data=df) -fit <- lmerTest::lmer(wt ~ mpg * cyl + (1|gear), data=df) +fit <- lm(wt ~ mpg * cyl, data = df) +fit <- lmerTest::lmer(wt ~ mpg * cyl + (1 | gear), data = df) summary(fit) standardize(fit) - } } diff --git a/man/standardize.numeric.Rd b/man/standardize.numeric.Rd index 36cab85..82505cb 100644 --- a/man/standardize.numeric.Rd +++ b/man/standardize.numeric.Rd @@ -17,10 +17,8 @@ Standardize (Z-score, "normalize") a vector. } \examples{ -standardize(x=c(1, 4, 6, 2)) -standardize(x=c(1, 4, 6, 2), normalize=TRUE) - - +standardize(x = c(1, 4, 6, 2)) +standardize(x = c(1, 4, 6, 2), normalize = TRUE) } \author{ \href{https://dominiquemakowski.github.io/}{Dominique Makowski} diff --git a/man/standardize.stanreg.Rd b/man/standardize.stanreg.Rd index bb0ad50..dd12d1d 100644 --- a/man/standardize.stanreg.Rd +++ b/man/standardize.stanreg.Rd @@ -21,11 +21,10 @@ Compute standardized posteriors from which to get standardized coefficients. library(psycho) library(rstanarm) -fit <- rstanarm::stan_glm(Sepal.Length ~ Sepal.Width * Species, data=iris) -fit <- rstanarm::stan_glm(Sepal.Length ~ Sepal.Width * Species, data=standardize(iris)) +fit <- rstanarm::stan_glm(Sepal.Length ~ Sepal.Width * Species, data = iris) +fit <- rstanarm::stan_glm(Sepal.Length ~ Sepal.Width * Species, data = standardize(iris)) posteriors <- standardize(fit) -posteriors <- standardize(fit, method="posterior") - +posteriors <- standardize(fit, method = "posterior") } }