Skip to content

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

@TarJae

Description

@TarJae

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions