cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar

Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

If you run a similar test like Tukey's JMP generates a "connecting letters report." However our data is non-normal and the variances are heterogeneous so we needed to use the Kruskal-Wallis test to examine variance and then used Steel-Dwass to compare means for all pairs of treatments. How can we get a similar letters report after doing this analysis?

Thanks,

Zach

10 REPLIES 10
dknayyar080
Level I

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

Were you able to get find a way to do this? I am currently need to do some steel dwass as well but have no idea how to get the connecting letters. Any help would be great. Thank you!

tpinck27
Level II

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

I've also been looking for a way to do this, I'm sure you could script it somehow but don't have the necessary scripting ability.

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

It appears there is no way built-in to the program, and I am not savvy with coding (hence using JMP instead of SAS). I imagine SAS has more options for this but I switched to JMP because of the ease of use. Depending on your data it may be fine to simply run an ANOVA and use Tukey's or similar if you can correct the variance with a tranformation or rely on the Welch ANOVA if not.

Turns out the assumption of normality does not always have to be met:

Experiments in Ecology, by A.J. Underwood. 2006. Cambridge University Press (pages 192-193)

joemama985
Level III

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

Four years later, still wishing it had this feature. 

txnelson
Super User

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

I would check to make sure the enhancement request is in the JMP Wish List, and if not, add it to the list

Jim
ukhan
Level I

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

Hi Jim (txnelson),
Any progress regarding adding/generating connecting letter report for nonparametric comparison (e.g., Kruskal-Wallis test)?
U.
txnelson
Super User

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

Not that I am aware of.
Jim
CurbGazelle
Level I

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

I thought I'd update this post as I've found a way of producing a compact letters display after non-parametric analysis with post-hoc pairwise comparisons. 

 

NOTE: This requires the open source and readily available statistical program R (I used RStudio, a more user-friendly version). 

 

After performing your non-parametric analysis in JMP, export the results table with pairwise p-values into an excel sheet. You then need to format the field of the comparison so that it is in one cell, with a single '-' separating the variables being compared. 

 

Then, in R, create a function using this script from https://rdrr.io/github/GegznaV/spMisc/src/R/eval_glue.R ::

#' [!] Format, parse and evaluate expression in a string
#'
#' A wrapper function to format and parse a string and evaluate it
#' as an expression. \code{eval_(X)} is a wrapper for
#' \code{eval(parse(text = glue::glue(X)))}.
#'
#' @details
#' It's a good practice to write backticks (`) arround variable names
#' to prevent from errors in situations, where variables have uncommon
#' names. See examples.
#'
#' @param ... Strings to be formatted and evaluated as an expression.
#' @param .open	 [\code{character(1)}: ‘\{’] \cr
#'        The opening delimiter. Doubling the full delimiter escapes it.
#' @param .close [\code{character(1)}: ‘\}’] \cr
#'        The closing delimiter. Doubling the full delimiter escapes it.
#' @inheritParams glue::glue
#' @inheritParams base::eval
#'
#' @export
#' @seealso Format and interpolate a string (\code{\link[glue]{glue}}).\cr
#'          Evaluate an (unevaluated) expression (\code{\link[base]{eval}}).\cr
#'          Parse expressions (\code{\link[base]{parse}}).
#' @examples
#' library("spMisc")
#'
#' AA <- "nn"
#'
#' glue::glue("{AA} <- 3")
#'
#' eval_glue("{AA} <- 3")
#'
#' AA
#'
#' nn
#'
#'  # It's a good practice to write backticks (`) arround variable names
#'  # to prevent from errors in situations, where variables have uncommon
#'  # names:
#'
#' BB <- "A B"
#'
#' eval_glue("`{BB}` <- 8")
#'
#' `A B`
#'
eval_glue <- function(..., envir = parent.frame(),
                      .sep = "", .open = "{", .close = "}") {

    x2 <- glue::glue(..., .envir = envir, .open = .open, .close = .close)
    eval(parse(text = x2), envir = envir)
}

 

 

Following this, make another function from this script from https://github.com/GegznaV/biostat/blob/master/R/make_cld_df.R ::

 

#' **[!!]** Make a data frame with cld
#'
#' Compute a compact letter display (cld) of statistically significant
#' differences in pairwise comparisons and output he results as a dataframe.
#'
#' @note
#' This function is based on code in function [rcompanion::cldList()]
#' from package \pkg{rcompanion} by Salvatore Mangiafico.
#'
#' @param swap_compared_names (logical) \cr If `TRUE`, group names are swapped
#' from, e.g., "2-1" or "second-first" to "1-2" or "first-second". This leads to
#' different order of cld letters and different order of compared groups (if
#' without swapping the result is incorrect order of groups.)
#'
#' @inheritParams rcompanion::cldList
#' @inheritParams multcompView::multcompLetters
#'
#' @export
#' @keywords internal

# @param comparison_order (character) Character vector with desired order of groups.
make_cld_df <- function(
formula = NULL,
data = NULL,
comparison = NULL,
p.value = NULL,
threshold = 0.05,
print.comp = FALSE,
remove.space = TRUE,
remove.equal = TRUE,
# remove.zero = TRUE,
swap.colon = TRUE,
swap.vs = FALSE,
reversed = FALSE,
swap_compared_names = FALSE,
# comparison_order = NULL,
...) {
if (!is.null(formula)) {
# # **[!!!]** Formula interface needs review.
# p.value = eval(parse(text = paste0("data", "$", all.vars(formula[[2]])[1])))
# comparison = eval(parse(text = paste0("data", "$", all.vars(formula[[3]])[1])))
p.value <- eval_glue("data${all.vars(formula[[2]])[1]}")
comparison <- eval_glue("data${all.vars(formula[[3]])[1]}")
}

significant_difference <- p.value < threshold
# if (sum(significant_difference) == 0) {
# stop("No significant differences.", call. = FALSE)
# }
if (remove.space == TRUE) {
comparison <- gsub(" ", "", comparison)
}
if (remove.equal == TRUE) {
comparison <- gsub("=", "", comparison)
}
# if (remove.zero == TRUE) {
# comparison = gsub("0", "", comparison)
# }
if (swap.colon == TRUE) {
comparison <- gsub(":", "-", comparison)
}
if (swap.vs == TRUE) {
comparison <- gsub("vs", "-", comparison)
}

if (swap_compared_names == TRUE) {
part_1 <- stringr::str_extract(comparison, ".*(?=-)")
part_2 <- stringr::str_extract(comparison, "(?<=-).*")
comparison <- paste0(part_2, "-", part_1)
}

comparison
names(significant_difference) <- comparison

if (print.comp == TRUE) {
Y <- data.frame(Comparisons = names(significant_difference))
cat("\n\n")
print(Y)
cat("\n\n")
}

MCL <- multcompView::multcompLetters(significant_difference, reversed = reversed)

regular_cld <- as.character(MCL$Letters)
spaced_cld <- as.character(MCL$monospacedLetters)

if (is.null(MCL$monospacedLetters)) {
spaced_cld <- regular_cld
} else {
spaced_cld <- spaced_cld
}

res <- data.frame(
group = names(MCL$Letters),
cld = as.character(MCL$Letters),
spaced_cld = gsub(" ", "_", spaced_cld)
)

structure(res, class = c("cld_object", class(res)))
}

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Helper function
# cld_update <- function(res) {
# res$MonoLetter <- gsub(" ", "_", res$MonoLetter)
# names(res) <- c("Group", "cld", "spaced_cld")
# structure(res, class = c("cld_object", class(res)))
# }

 

You can then apply the newly made make_cld_df function to your data in the form of::

 

x<-make_cld_df(p.value~pairwisecomparison, data=data. 

then call x

 

 

yelnats
Level I

Re: Can you generate a letters report after conducting the Steel-Dwass nonparameteric comparison?

Can you (or someone else) post a complete example of a small input file, the code and the output for the above process to carry out the compact letters display after non-parametric analysis with post-hoc pairwise comparisons from an excel or text input file.