Skip to content
This repository has been archived by the owner on Mar 24, 2022. It is now read-only.

Commit

Permalink
closes #21
Browse files Browse the repository at this point in the history
  • Loading branch information
IndrajeetPatil committed Sep 28, 2020
1 parent eecdb7d commit 8fe11d0
Show file tree
Hide file tree
Showing 16 changed files with 310 additions and 174 deletions.
5 changes: 0 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,12 @@ r_packages:
- mvtnorm
- rstan
- StanHeaders
- LaplacesDemon
- logspline
- testthat
- remotes
- knitr
- rmarkdown
- coda
- rstantools
- bridgesampling
- BH
- metaBMA

r_github_packages:
- jimhester/lintr
Expand Down
1 change: 1 addition & 0 deletions API
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
p_adjust_text(p.adjust.method)
pairwise_caption(caption, test.description, pairwise.display = "significant", ...)
pairwise_comparisons(data, x, y, type = "parametric", paired = FALSE, var.equal = FALSE, tr = 0.1, bf.prior = 0.707, p.adjust.method = "holm", k = 2L, ...)
pairwise_p(data, x, y, type = "parametric", paired = FALSE, var.equal = FALSE, tr = 0.1, bf.prior = 0.707, p.adjust.method = "holm", k = 2L, ...)

## Reexported objects

Expand Down
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ Depends:
R (>= 3.6.0)
Imports:
broom,
BayesFactor,
dplyr,
ipmisc,
PMCMRplus,
parameters,
purrr,
rlang,
stats,
tidyBF (>= 0.2.1),
tidyr,
WRS2
Suggests:
Expand Down
5 changes: 4 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ export(long_to_wide_converter)
export(p_adjust_text)
export(pairwise_caption)
export(pairwise_comparisons)
export(pairwise_p)
export(signif_column)
export(specify_decimal_p)
export(tibble)
importFrom(BayesFactor,ttestBF)
importFrom(PMCMRplus,durbinAllPairsTest)
importFrom(PMCMRplus,gamesHowellTest)
importFrom(PMCMRplus,kwAllPairsDunnTest)
Expand All @@ -41,12 +43,14 @@ importFrom(ipmisc,"%<-%")
importFrom(ipmisc,"%<>%")
importFrom(ipmisc,"%>%")
importFrom(ipmisc,as_tibble)
importFrom(ipmisc,easystats_to_tidy_names)
importFrom(ipmisc,enframe)
importFrom(ipmisc,long_to_wide_converter)
importFrom(ipmisc,signif_column)
importFrom(ipmisc,specify_decimal_p)
importFrom(ipmisc,stats_type_switch)
importFrom(ipmisc,tibble)
importFrom(parameters,model_parameters)
importFrom(purrr,map2)
importFrom(purrr,map_dfr)
importFrom(rlang,"!!")
Expand All @@ -60,7 +64,6 @@ importFrom(stats,aov)
importFrom(stats,na.omit)
importFrom(stats,p.adjust)
importFrom(stats,pairwise.t.test)
importFrom(tidyBF,bf_ttest)
importFrom(tidyr,gather)
importFrom(tidyr,separate)
importFrom(tidyr,spread)
1 change: 1 addition & 0 deletions R/global_vars.R
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ utils::globalVariables(
"R",
"adj.r.squared",
"p.value",
"psihat",
"term",
"label",
"loglik",
Expand Down
70 changes: 68 additions & 2 deletions R/helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ PMCMR_to_tibble <- function(mod, ...) {
)
}



#' @name p_adjust_column_adder
#'
#' @importFrom stats p.adjust
#' @importFrom dplyr mutate
#'
#' @noRd
#' @keywords internal

Expand All @@ -42,3 +45,66 @@ p_adjust_column_adder <- function(df, p.adjust.method) {
dplyr::mutate(p.value = stats::p.adjust(p = p.value, method = p.adjust.method)) %>%
signif_column(data = ., p = p.value)
}

#' @importFrom BayesFactor ttestBF
#' @importFrom dplyr mutate
#' @importFrom parameters model_parameters
#' @importFrom ipmisc easystats_to_tidy_names
#'
#' @noRd
#' @keywords internal

bf_internal_ttest <- function(data,
x,
y,
paired = FALSE,
bf.prior = 0.707,
...) {
# make sure both quoted and unquoted arguments are allowed
c(x, y) %<-% c(rlang::ensym(x), rlang::ensym(y))

# have a proper cleanup with NA removal
data %<>%
ipmisc::long_to_wide_converter(
data = .,
x = {{ x }},
y = {{ y }},
paired = paired,
spread = paired
)

# within-subjects design
if (isTRUE(paired)) {
# change names for convenience
colnames(data) <- c("rowid", "col1", "col2")

# extracting results from Bayesian test and creating a dataframe
bf_object <-
BayesFactor::ttestBF(
x = data$col1,
y = data$col2,
rscale = bf.prior,
paired = TRUE,
progress = FALSE
)
}

# between-subjects design
if (isFALSE(paired)) {
# extracting results from Bayesian test and creating a dataframe
bf_object <-
BayesFactor::ttestBF(
formula = rlang::new_formula({{ y }}, {{ x }}),
data = as.data.frame(data),
rscale = bf.prior,
paired = FALSE,
progress = FALSE
)
}

# extracting Bayes Factors and other details
parameters::model_parameters(bf_object, ...) %>%
ipmisc::easystats_to_tidy_names(.) %>%
dplyr::rename(.data = ., bf10 = bf) %>%
dplyr::mutate(.data = ., log_e_bf10 = log(bf10))
}
84 changes: 47 additions & 37 deletions R/pairwise_comparisons.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#' @title Multiple pairwise comparison tests with tidy data
#' @name pairwise_comparisons
#' @description Calculate parametric, non-parametric, and robust pairwise
#' comparisons between group levels with corrections for multiple testing.
#' @description Calculate parametric, non-parametric, robust, and Bayes Factor
#' pairwise comparisons between group levels with corrections for multiple
#' testing.
#'
#' @param data A dataframe from which variables specified are to be taken. A
#' matrix or tables will **not** be accepted.
Expand Down Expand Up @@ -38,6 +39,21 @@
#' columns across the different types of statistics, there will be additional
#' columns specific to the `type` of test being run.
#'
#' This function provides a unified syntax to carry out pairwise comparison
#' tests and internally relies on other packages to carry out these tests. For
#' more details about the included tests, see the documentation for the
#' respective functions:
#' \itemize{
#' \item *parametric* : [stats::pairwise.t.test()] (paired) and
#' [PMCMRplus::gamesHowellTest()] (unpaired)
#' \item *non-parametric* :
#' [PMCMRplus::durbinAllPairsTest()] (paired) and
#' [PMCMRplus::kwAllPairsDunnTest()] (unpaired)
#' \item *robust* :
#' [WRS2::rmmcp()] (paired) and [WRS2::lincon()] (unpaired)
#' \item *Bayes Factor* : [BayesFactor::ttestBF()]
#' }
#'
#' The `significance` column asterisks indicate significance levels of
#' *p*-values in the American Psychological Association (APA) mandated format:
#' \itemize{
Expand All @@ -57,7 +73,6 @@
#' @importFrom purrr map2 map_dfr
#' @importFrom broom tidy
#' @importFrom ipmisc stats_type_switch
#' @importFrom tidyBF bf_ttest
#'
#' @examples
#'
Expand Down Expand Up @@ -182,8 +197,7 @@ pairwise_comparisons <- function(data,
type <- ipmisc::stats_type_switch(type)

# ensure the arguments work quoted or unquoted
x <- rlang::ensym(x)
y <- rlang::ensym(y)
c(x, y) %<-% c(rlang::ensym(x), rlang::ensym(y))

# ---------------------------- data cleanup -------------------------------

Expand Down Expand Up @@ -241,27 +255,23 @@ pairwise_comparisons <- function(data,

# ---------------------------- bayes factor --------------------------------

# print a message telling the user that this is currently not supported
if (type == "bayes") {
# creating a list of dataframes with subsections of data
df_list <-
purrr::map2(
.x = as.character(df$group1),
.y = as.character(df$group2),
.f = function(a, b) droplevels(dplyr::filter(df_internal, {{ x }} %in% c(a, b)))
)

# combining results into a single dataframe and returning it
df_tidy <-
purrr::map_dfr(
.x = df_list,
.f = ~ tidyBF::bf_ttest(
# creating a list of dataframes with subsections of data
.x = purrr::map2(
.x = as.character(df$group1),
.y = as.character(df$group2),
.f = function(a, b) droplevels(dplyr::filter(df_internal, {{ x }} %in% c(a, b)))
),
# internal function to carry out BF t-test
.f = ~ bf_internal_ttest(
data = .x,
x = {{ x }},
y = {{ y }},
paired = paired,
bf.prior = bf.prior,
output = "results"
bf.prior = bf.prior
)
) %>%
dplyr::rowwise() %>%
Expand All @@ -285,8 +295,8 @@ pairwise_comparisons <- function(data,
# ---------------------------- nonparametric ----------------------------

if (type == "nonparametric") {
# # running Dunn test
if (isFALSE(paired)) {
# # running Dunn test
mod <-
suppressWarnings(PMCMRplus::kwAllPairsDunnTest(
x = y_vec,
Expand All @@ -299,9 +309,8 @@ pairwise_comparisons <- function(data,
test.details <- "Dunn test"
}

# converting the entered long format data to wide format
# # running Durbin-Conover test
if (isTRUE(paired)) {
# creating model object
mod <-
PMCMRplus::durbinAllPairsTest(
y = na.omit(matrix(
Expand All @@ -326,20 +335,16 @@ pairwise_comparisons <- function(data,

if (type == "robust") {
if (isFALSE(paired)) {
# object with all details about pairwise comparisons
rob_pairwise_df <-
wrs_obj <-
WRS2::lincon(
formula = rlang::new_formula({{ y }}, {{ x }}),
data = df_internal,
tr = tr
)
}

# converting to long format and then getting it back in wide so that the
# rowid variable can be used as the block variable
if (isTRUE(paired)) {
# running pairwise multiple comparison tests
rob_pairwise_df <-
wrs_obj <-
WRS2::rmmcp(
y = df_internal[[rlang::as_name(y)]],
groups = df_internal[[rlang::as_name(x)]],
Expand All @@ -350,22 +355,21 @@ pairwise_comparisons <- function(data,

# extracting the robust pairwise comparisons and tidying up names
rob_df_tidy <-
suppressMessages(as_tibble(rob_pairwise_df$comp, .name_repair = "unique")) %>%
suppressMessages(as_tibble(wrs_obj$comp, .name_repair = "unique")) %>%
dplyr::rename(group1 = Group...1, group2 = Group...2)

# cleaning the raw object and getting it in the right format
df <-
dplyr::full_join(
# dataframe comparing comparison details
x = p_adjust_column_adder(df = rob_df_tidy, p.adjust.method = p.adjust.method) %>%
tidyr::gather(
data = .,
key = "key",
value = "rowid",
group1:group2
),
x = tidyr::gather(
data = p_adjust_column_adder(rob_df_tidy, p.adjust.method),
key = "key",
value = "rowid",
group1:group2
),
# dataframe with factor levels
y = enframe(x = rob_pairwise_df$fnames, name = "rowid"),
y = enframe(x = wrs_obj$fnames, name = "rowid"),
by = "rowid"
) %>%
dplyr::select(.data = ., -rowid) %>%
Expand All @@ -375,7 +379,7 @@ pairwise_comparisons <- function(data,
if (("p.crit") %in% names(df)) df %<>% dplyr::select(.data = ., -p.crit)

# renaming confidence interval names
df %<>% dplyr::rename(.data = ., conf.low = ci.lower, conf.high = ci.upper)
df %<>% dplyr::rename(estimate = psihat, conf.low = ci.lower, conf.high = ci.upper)

# test details
test.details <- "Yuen's trimmed means test"
Expand Down Expand Up @@ -428,3 +432,9 @@ pairwise_comparisons <- function(data,
# return
return(dplyr::ungroup(df))
}

#' @name pairwise_comparisons
#' @aliases pairwise_comparisons
#' @export

pairwise_p <- pairwise_comparisons
Loading

3 comments on commit 8fe11d0

@lintr-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R/pairwise_comparisons.R:185:1: style: functions should have cyclomatic complexity of less than 15, this has 18.

pairwise_comparisons <- function(data,
^

@lintr-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R/pairwise_comparisons.R:185:1: style: functions should have cyclomatic complexity of less than 15, this has 18.

pairwise_comparisons <- function(data,
^

@lintr-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R/pairwise_comparisons.R:185:1: style: functions should have cyclomatic complexity of less than 15, this has 18.

pairwise_comparisons <- function(data,
^

Please sign in to comment.