Search code examples
rdataframepercentagelikert

How do I add percentages beside frequency values in a one-way frequency table?


I just recently started using R, and it's also my first time posting here (sorry if I miss a few details my question). I have a dataset that contains around 22 questions/statements that are in 5 pt. Likert-scale format. Each statement has a dedicated column with the respective answers under it.

Here is a sample data frame of what it looks like (but with only 3 columns instead of 22):

q1 = c(1, 2, 2, 1, 3, 4, 3, 5, 2, 2)
q2 = c(2, 3, 5, 5, 4, 5, 1, 1, 5, 3)
q3 = c(4, 4, 2, 3, 2, 1, 1, 1, 5, 5)
data <- data.frame(q1, q2, q3)
colnames(data) = c("This is statement 1.", "This is statement 2.", "This is statement 3.")
data 

I have a few specific requirements for it:

  1. It needs to be horizontal, so that each statement and its responses will form one row. It would be too long if I have it set vertically for each of the 22 questions.
  2. If possible, it should be compatible with knitr :: kable (compatible meaning it looks decent when knit in R Markdown)
  3. Each element in the data frame should have a corresponding row percentage enclosed in parenthesis.
  4. The header of the table should be 1, 2, 3, 4, 5 (since they are all 5 pt. Likert scale questions)

Here is a screenshot similar to what I wanted to achieve (taken from https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3490724/): In the reference picture, each question and the responses (yes/no, with their percentages in parentheses) took up 1 row, making it compact. Each frequency had a corresponding row percentage in parenthesis. I want the same thing, but instead of yes and no, it should have headers: 1, 2, 3, 4, 5.

I tried using table function, but I couldn't figure out how to add the percentage values to each element in the data frame. Thanks in advance!


Solution

  • We could use tidyr to arrange the data, janitor to create the table and format the percentages, and knitr/gt to make it prettier ;)

    library(tidyr)
    library(janitor)
    library(gt)
    
    data |>
      pivot_longer(everything(),
                   names_to = "Question") |>
        tabyl(Question, value) |>
        adorn_percentages("row") |>
        adorn_pct_formatting(digits = 0) |>
        adorn_ns(position = "front") |>
        gt() # knitr::kable()
    

    Output:

    enter image description here