Search code examples
rformattable

Troubleshooting R table function to create a more complete-looking table


I'm attempting to create a table of relative percentage values for answers to a questionnaire (answers are graded 1-5) for a total of 3 questions.

I'm using the formattable library to convert the values in the tables to percents, but thus far I am unable to combine the results for Questions 1, 2, and 3 into 1 table. The code I have written is:

tableq1<-percent(table(Q1val)/length(na.omit(Q1val)))
tableq1

The current output is:

enter image description here

What do I need to do in order to achieve this? Ultimately, I want to have this table as a pdf or png, with gridlines that make it look clean and professional.

Per request:

dput(Q1val)

c(4, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 3, 4, 5, 
4, 5, 1, 5, 5, 5, 4, 5, 4, 3, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 
5, 5, 3, 5, 5, 4, 4, 4, 4, 5, 2, 5, 4, NA, 5, 5, 5, 3, 5, 5, 
4, 5, 5, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4, 5, 5, 5, 5, 5, 4, 5, 4, 
4, 3, 5, 4, 4, 5, 5, 5, 4, 5, 4, 5, 4, 4, 3, 5, 5, 5, 5, 4, 3, 
4, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 5, 4, 4, 4, 5, 4, 4, 5, 5, 5, 
5, 5, 4, 4, 5, 4, 5, 5, 5, 2, 4, 2, 5, 5, 3, 4, 3, 4, 5, 5, 4, 
4, 3, 5, 5, 4, 5, 4, 3, 5, 3, 4, 4, 5, 4, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 4, 5, 5, 3, 3, 4, 5, 4, 5, 5 # , ...
)

Solution

  • In an improvement over my comments, I've chosen to render the result with the kableExtra package.

    Solution

    First load the appropriate packages:

    library(dplyr)
    library(formattable)
    library(kableExtra)
    

    Once you've generated the Q*val vectors in your workspace...

    # ...
    # Code to generate 'Q1val', 'Q2val', ...
    # ...
    

    ...then run this workflow to consolidate them into a single contingency table:

    # Identify all the 'Q*val' vectors.
    q_names <- ls(pattern = "Q\\d+val")
    
    
    # Assemble a single table.
    q_all <- q_names %>%
      # Capture those vectors in a (named) list.
      mget(inherits = TRUE) %>%
      # Turn each vector into a contingency table of percentages.
      sapply(
        FUN = function(x) { 
          percent(table(x) / length(na.omit(x)))
        },
        simplify = FALSE
      ) %>%
      # Stack those contingency tables into a single table.
      do.call(what = bind_rows) %>%
      # Convert to 'data.frame' to preserve row names.
      as.data.frame() %>%
      # Add row names of "Q1", "Q2", ...; as extracted from the names "Q1val", "Q2val", ...
      `rownames<-`(value = gsub(
         x = q_names,
         pattern = "^(Q\\d+)(val)$",
         replacement = "\\1"
      ))
    

    You can then prettify the table and export it as an image.

    # Prettify the table.
    q_pretty <- q_all %>%
      # Convert into 'kable' object.
      kbl() %>%
      # Border the rows and stripe the cells.
      kable_styling(
        bootstrap_options = c("bordered", "striped")
        
        # ...
        # Further styling as desired.
        # ...
        
      ) # %>%
      
      # ...
      # Further 'kable' adjustments as desired.
      # ...
    
    
    # Save pretty table as PNG image.
    save_kable(
      x = q_pretty,
      file = "pretty.png"
    )
    

    Note

    You can easily save as a PDF by replacing "pretty.png" with "pretty.pdf".

    Result

    I had to improvise my own Q2val and Q3val, but the resulting pretty.png should look like this: 2