rtidyverselikert

R: Convert sav (SPSS) data to a format suitable for HH::likert


I'm trying to convert data from a sav (SPSS) data file to a format suitable for plotting by HH::likert, and I can't get the proper invocation to do this.

To replicate the sav format, create a dataframe giving the results of a likert question on rating particular cheeses from 1 (strongly like) to 5 (strongly dislike) as answered by 7 respondents:

cheeses<-tribble(
  ~Cheddar, ~Brie, ~Stilton,
  1, 4, 2, 
  2, 4, 1,
  1, 1, 3,
  4, 1, 5,
  3, 2, 4,
  5, 3, 1,
  1, 5, 2
)

Pivoting longer doesn't give a dataframe that can be used by HH::Likert - it plots, but the chart simply compares rating versus n(umber):

cheeseslong<-cheeses %>% 
  pivot_longer(everything(), names_to = "question", values_to = "rating") %>%
  count(question, rating) %>% 
  group_by(question, rating)

The data needs to be in this format, which totals the number of responses for each rating of each cheese:

cheeseslikert<-tribble(
  ~Question, ~"Strongly like", ~Like, ~Unsure, ~Dislike, ~"Strongly dislike",
  "Cheddar", 3, 1, 1, 1, 1,
  "Brie", 2, 1, 1, 2, 1,
  "Stilton", 2, 2, 0, 0, 3
)

We can then plot the likert chart nicely:

HH::likert(Question~.,
           cheeseslikert,
           positive.order=TRUE,
           as.percent = TRUE,
           main="Cheese preferences.",
           xlab="percentage",
           ylab=""
)

Likert chart for cheese preference

So my question is: what commands should be used to move the data from the "cheeses" format to the "cheeseslikert" format? Ideally, I'd like a tidyverse solution, but a base R solution would also be fine.


Solution

  • You would need to pivot_wider after pivot_longer (and introduce labels before or after first pivot):

    library(tidyverse)
    
    cheeses<-tribble(
      ~Cheddar, ~Brie, ~Stilton,
      1, 4, 2, 
      2, 4, 1,
      1, 1, 3,
      4, 1, 5,
      3, 2, 4,
      5, 3, 1,
      1, 5, 2
    )
    
    cheeseslikert <- cheeses |>
      mutate(across(
        everything(),
        factor,
        labels = c("Strongly like", "Like", "Unsure", "Dislike", "Strongly dislike")
      )) |>
      pivot_longer(everything(), names_to = "question", values_to = "rating") |>
      count(question, rating) |>
      pivot_wider(names_from = rating, values_from = n)
    
    HH::likert(
      question ~ .,
      cheeseslikert,
      positive.order = TRUE,
      as.percent = TRUE,
      main = "Cheese preferences.",
      xlab = "percentage",
      ylab = ""
    )