Format complex tables using janitor package in R

Hello RStudio community,
I need help with with formating tables using janitor package in R if somebody can help me. It is appreciated. Thanks

# In the first table, how to get the table by having values first and then percent in the bracket format (value (%))?

library(dplyr)
humans <- starwars %>%
  filter(species == "Human")

# table1
library(janitor)
humans %>%
  tabyl(eye_color, skin_color, gender, show_missing_levels = FALSE) %>%
  adorn_totals(c("row", "col")) %>%
  adorn_percentages("row") %>%
  adorn_pct_formatting(digits = 1) %>%
  adorn_ns %>%
  adorn_title

#table2 
# table 2 is similar to table 1 with using knitr::kable(). How to get subtiles for  sub-group table  (feminine) and sub-group table  (masculine) ?
humans %>%
  tabyl(eye_color, skin_color, gender, show_missing_levels = FALSE) %>%
  adorn_totals(c("row", "col")) %>%
  adorn_percentages("row") %>% 
  adorn_pct_formatting(rounding = "half up", digits = 0) %>%
  adorn_ns() %>%
  adorn_title("combined") %>%
  knitr::kable()

my understanding is that janitor doesnt support doing what you are asking for

Do you know any other functions in R. I need the tables in those format if you or somebody can help me. Thanks

There's this sort of approach:

library(tidyverse) #for both dplyr & purrr


join_cell <- function(n,p){
  paste0(n," (",p,")")
}
#test 
join_cell(5,"20.0%")
#[1] "5 (20.0%)"

join_table <- function(nt,pt){
  first_col <- nt |> select(1)
  nt <- nt |> select(-1)
  pt <- pt |> select(-1)
  if(! identical(dim(nt),dim(pt))){
    stop("the tables should be the same shapes, or what are we doing here?")
  }
  res <- array(data=NA_character_,
              dim = dim(nt)) |> as.data.frame()
  names(res) <- names(nt)
  for (j in seq_len(nrow(nt))){
    for(i in seq_len(ncol(nt))){
      res[j,i] <- join_cell(nt[j,i],pt[j,i])
    }
  }
  bind_cols(first_col,res)
}
#test
join_table(data.frame(x=rep("x",2),a=1:2,b=3:4),
           data.frame(x=rep("x",2),a=scales::percent((1:2)/10),
                      b=scales::percent((3:4)/10)))

# x       a       b
# 1 x 1 (10%) 3 (30%)
# 2 x 2 (20%) 4 (40%)

humans <- starwars %>%
  filter(species == "Human")

library(janitor)

(tybl_n <- humans %>%
  tabyl(eye_color, skin_color, gender, show_missing_levels = FALSE) %>%
  adorn_totals(c("row", "col")))

(tyble_perc <- tybl_n %>%
  adorn_percentages("row") %>%
  adorn_pct_formatting(digits = 1) )

(custom_df_list <- map2(tybl_n,
     tyble_perc,
     join_table))
1 Like

You might want to have a look at flextable. It seems rather versatile. Or another package from the same author, gtsummary, might work. Disclaimer, I have never used gtsummary.

As nirgrahamuk says it does not look like janitor will do what you need.

1 Like

This is what exactly I wanted. Thanks

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.