Datasummary - Plot histograms side-by-side

Viewed 48

I would like to use the functionality of modelsummary::datasummary_skim such that two tables are aligned side-by-side including the histograms and only the mean of the variables, e.g.

library(modelsummary)
library(dplyr)
library(kableExtra)

normal_df <- data.frame(
  var1 = c(1:3, 50:53, 100:102),
  var2 = runif(10),
  var3 = seq(10, 100, 10)
)


outlier_df <- tibble::tribble(
  ~var1, ~var2, ~var3,
  1, 1000, 10.5,
  2, 20000, 100.6,
  3, 32, 1000.3
) %>% as.data.frame()

# This is how datasummary_skim looks like
datasummary_skim(normal_df)

# this is how it could work using datasummary
datasummary(All(normal_df) ~ Mean + Histogram, normal_df) %>%
  kable_styling(full_width = FALSE, position = "float_left") %>%
  add_header_above(c("", "Normal" = 2))
datasummary(All(outlier_df) ~ Mean + Histogram, outlier_df) %>%
  kable_styling(full_width = FALSE, position = "left") %>%
  add_header_above(c("", "Outlier" = 2))

The problem is that the histograms are not displayed anymore. Any ideas/hints are much appreciated!

2 Answers

EDIT: As pointed out in the comments below, this may not work on all operating systems (Works on Debian 11)

One way to solve this is to combine all the data in a single data frame, then use the nesting feature in datasummary -

normal_df$type <- "normal"
outlier_df$type <- "outlier"
all_df <- rbind(normal_df,outlier_df)
datasummary(All(all_df) ~ (Mean + Histogram) * type,
            data = all_df)

Output

I solved my problem thanks to @Vincent.

tmp_list <- lapply(normal_df, na.omit)
tmp_list <- lapply(tmp_list, scale)

tmp_list2 <- lapply(outlier_df, na.omit)
tmp_list2 <- lapply(tmp_list2, scale)


emptycol = function(x) " "


kbl1 <- datasummary(All(normal_df) ~ Mean + SD + Heading("Boxplot") * emptycol + Heading("Histogram") * emptycol, data = normal_df) %>%
  column_spec(column = 4, image = spec_boxplot(tmp_list, same_lim = FALSE)) %>%
  column_spec(column = 5, image = spec_hist(tmp_list, same_lim = FALSE)) %>%
  kable_styling(full_width = FALSE, position = "float_left", font_size = 12) %>%
  add_header_above(c("", "Normal" = 4))

kbl2 <- datasummary(All(outlier_df) ~ Mean + SD + Heading("Boxplot") * emptycol +
                      Heading("Histogram") * emptycol, data = outlier_df) %>%
  column_spec(column = 4, image = spec_boxplot(tmp_list2, same_lim = FALSE)) %>%
  column_spec(column = 5, image = spec_hist(tmp_list2, same_lim = FALSE)) %>%
  kable_styling(full_width = FALSE, position = "left", font_size = 12) %>%
  add_header_above(c("", "Outlier" = 4))

knitr::kables(list(kbl1,kbl2)) %>% kable_styling()
Related