Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the group.order argument in likert.heat.plot #140

Open
TarJae opened this issue Jun 3, 2024 · 0 comments
Open

Implement the group.order argument in likert.heat.plot #140

TarJae opened this issue Jun 3, 2024 · 0 comments

Comments

@TarJae
Copy link

TarJae commented Jun 3, 2024

The order of the items is as intended in type=bar using group.order argument, but reversed when using type=heat.
Consider this MRE:

library(likert)
items24 <- pisaitems[,substr(names(pisaitems), 1,5) == 'ST24Q']
l24 <- likert(items24)

plot(l24, type = "bar", group.order = names(items24))
plot(l24, type = "heat", group.order = names(items24))

image
image

The documentations says: plot.likert is an implementation of the S3 plot generic function. Based upon the type parameter this function will call either likert.bar.plot, likert.heat.plot or likert.density.plot.
likert.bar.plot has a group.order argument
likert.heat.plot does not have a group.order argument.

I managed to implement a likert.heat.plot with the group.order argument:

likert.heat.plot <- function(likert, low.color = "white", high.color = "blue", text.color = "black", 
                             text.size = 4, wrap = 50, group.order = NULL, ...) 
{
  if (!is.null(likert$grouping)) {
    stop("heat plots with grouping are not supported.")
  }
  lsum <- summary(likert)
  results <- reshape2::melt(likert$results, id.vars = "Item")
  results$variable <- as.character(results$variable)
  results$label <- paste(format(results$value, digits = 2, drop0trailing = FALSE), 
                         "%", sep = "")
  tmp <- data.frame(Item = lsum$Item, variable = rep("Mean (SD)", 
                                                     nrow(lsum)), value = rep(-100, nrow(lsum)), label = paste(format(lsum$mean, 
                                                                                                                      digits = 3, drop0trailing = FALSE), " (", format(lsum$sd, 
                                                                                                                                                                       digits = 2, drop0trailing = FALSE), ")", sep = ""), stringsAsFactors = FALSE)
  results <- rbind(tmp, results)
  
  # Apply group.order if specified
  if (!is.null(group.order)) {
    results$Item <- factor(results$Item, levels = group.order)
    lsum$Item <- factor(lsum$Item, levels = group.order)
  }
  
  p <- ggplot(results, aes(x = Item, y = variable, fill = value, 
                           label = label)) + 
    scale_y_discrete(limits = c("Mean (SD)", names(likert$results)[2:ncol(likert$results)])) + 
    geom_tile() + 
    geom_text(size = text.size, colour = text.color) + 
    coord_flip() + 
    scale_fill_gradient2("Percent", low = low.color, high = high.color, limits = c(0, 100)) + 
    xlab("") + 
    ylab("") + 
    theme(panel.grid.major = element_blank(), 
          panel.grid.minor = element_blank(), 
          axis.ticks = element_blank(), 
          panel.background = element_blank())
  
  if (!is.null(group.order)) {
    p <- p + scale_x_discrete(limits = rev(group.order), labels = stringr::str_wrap(rev(group.order), width = wrap))
  } else {
    p <- p + scale_x_discrete(breaks = likert$results$Item, labels = stringr::str_wrap(likert$results$Item, width = wrap))
  }
  
  class(p) <- c("likert.heat.plot", class(p))
  return(p)
}

Or should we just use:

library(likert)
library(ggplot2)
plot(l24, type = "heat", group.order = names(items24)) +
  scale_x_discrete(limits=rev)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant