0

I have this code which prints multiple tables

    library(tidyverse)
    library(dplyr)
    library(purrr)
    
    u<- c("D", "B", "C", "A")
    
    l<- list(`0` = structure(list(X70 = "D", X71 = "C", X72 = "C", X73 = "A", X74 = "B", X75 = "C", X76 = "D", X77 = NA_character_, X78 = "B", X79 = "D", X80 = "C", Q = 1), row.names = 32L, class = "data.frame"), `1` = structure(list(X70 = c("D", "B", "D", "D", "B", "D", "D", "D", "D", "D", "D"), X71 = c("B", "B", "C", "C", "C", NA, "D", "B", "C", "A", "C"), X72 = c("A", "A", "C", "B", "C", "C", "C", "C", "D", "B", NA), X73 = c("B", "C", "C", "B", "C", "D", "A", "B", "C", "C", NA), X74 = c("B", "A", "C", "D", "B", "D", NA, "D", "D", "D", NA), X75 = c("C", "C", "B", "C", "D", "D", "C", "A", "C", "C", "C"), X76 = c("D", "A", "D", "B", "D", "C", "D", "A", "A", "D", "B"), X77 = c("D", "C", "B", "B", "B", "C", "B", "B", "B", "B", "D"), X78 = c("B", "C", "C", "B", "A", "A", "C", "B", "A", "C", NA), X79 = c("C", "C", NA, NA, "D", "A", "A", "A", "D", "A", "D"), X80 = c("B", "A", NA, NA, "B", "C", "B", NA, "B", "C", "A"), Q = c(2, 2, 1, 1, 2, 2, 1, 1, 4, 3, 1)), row.names = c(8L, 10L, 12L, 17L, 25L, 27L, 28L, 33L, 35L, 38L, 45L), class = "data.frame"), `2` = structure(list(X70 = c("D", "D", "D", "B", "D", "C", "D", "D", "D", "D", "D", "D"), X71 = c("A", "B", "C", "C", "A", "A", "C", "B", "C", "C", "D", "B"), X72 = c("D", "C", "D", "A", "A", "C", "D", "C", NA, "D", "C", "B"), X73 = c("B", "D", "D", "C", "B", "D", "D", "D", NA, NA, "C", "A"), X74 = c("D", "C", "B", "D", "C", "B", "C", "C", "B", NA, "C", "D"), X75 = c("B", "C", "C", "C", NA, "C", "B", "C", "C", "C", "B", "C"), X76 = c("A", "D", "D", "D", NA, "D", "D", "A", "D", "D", "D", "D"), X77 = c("B", "B", "D", "B", NA, "B", "D", "B", "B", "B", "B", "B"), X78 = c("C", "D", "C", "B", NA, "D", "C", "C", "B", "D", "C", NA), X79 = c("A", "D", "D", "D", NA, "D", "A", NA, "A", "D", "B", NA), X80 = c(NA, "C", "C", "A", NA, "C", "C", NA, "B", "C", "C", NA), Q = c(2, 3, 3, 1, 3, 1, 2, 2, 1, 2, 2, 1)), row.names = c(4L, 5L, 6L, 11L, 15L, 16L, 21L, 22L, 26L, 37L, 39L, 43L), class = "data.frame"), `3` = structure(list(X70 = c("A", "A", "D", "C", "D", "D", "D", "D", NA, "D", "D", "D"), X71 = c("B", "C", "D", "D", "C", "C", "B", "C", "C", "C", "A", "D"), X72 = c("B", "C", NA, "B", "A", "C", "B", "A", "C", "C", "D", "B"), X73 = c(NA, "C", "C", "A", "D", "C", "A", "A", "D", "B", "D", "B"), X74 = c(NA, "C", "D", "B", "A", "D", NA, "D", "B", "A", "D", "A"), X75 = c(NA, "C", "B", "D", "C", "C", "C", "C", "C", "B", "C", "D"), X76 = c(NA, "D", "A", "B", "A", "D", "D", "D", "D", "D", "D", "D"), X77 = c(NA, "B", "B", "B", "C", "B", "A", "B", NA, "C", "D", "D"), X78 = c(NA, "C", "C", "B", "C", "B", "A", "C", "D", "C", "C", "C"), X79 = c(NA, "D", "D", NA, "B", "D", "A", "D", "A", "D", "D", "A"), X80 = c(NA, "C", "C", NA, "D", "C", "C", "C", "C", "C", "B", "C"), Q = c(2, 2, 2, 2, 4, 2, 4, 4, 4, 3, 3, 2)), row.names = c(2L, 13L, 14L, 18L, 19L, 20L, 29L, 30L, 34L, 36L, 41L, 44L), class = "data.frame"), `4` = structure(list(X70 = c("D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D"), X71 = c("A", NA, "A", "B", "C", "A", "A", "C", "B", "C", "C", "C"), X72 = c("B", "C", "C", "C", NA, "C", "B", "A", "C", "B", NA, "A"), X73 = c(NA, "D", "D", "D", "B", "D", "D", "D", "C", "A", "A", "C"), X74 = c("C", "A", "C", "D", "C", "C", "A", "A", "C", "D", "D", "D"), X75 = c("C", "C", "C", "C", "C", "C", "C", "C", "C", "D", "C", "C"), X76 = c("D", "D", "D", "D", "D", "D", "D", "D", "A", "D", "D", "A"), X77 = c(NA, "B", "D", "B", NA, "B", "B", "B", "C", "D", NA, "C"), X78 = c("C", "C", "C", "C", "A", "A", "C", "A", "C", "C", "C", "C"), X79 = c("D", "D", "A", "D", "D", "A", "D", "D", "A", "D", "C", "C"), X80 = c("C", "C", "C", "C", NA, "C", "C", "C", "C", "C", "C", "A"), Q = c(2, 4, 4, 3, 2, 4, 2, 4, 1, 1, 2, 4)), row.names = c(1L, 3L, 7L, 9L, 23L, 24L, 31L, 40L, 42L, 46L, 47L, 48L), class = "data.frame"))
    
    
    out <- lapply(l, function(dat) 
       asplit(as.data.frame(t(sapply(dat, function(x) 
                proportions(table(factor(unlist(x), levels = u)))))), 1) ) %>%
        transpose %>%
        map(bind_rows, .id = 'grp')

out

I want to print using ggplot for each table because it looks very beautiful and also has A,B,C,D at the end of each line. Here is an example code which prints a ggplot for one table. I want to print this type of table for each table print by out above.

library(tidyverse)

d = structure(c(0.129310344827586, 0.258620689655172, 0.318965517241379, 
        0.293103448275862, 0.12972972972973, 0.210810810810811, 0.345945945945946, 
        0.313513513513514, 0.0845070422535211, 0.154929577464789, 0.338028169014085, 
        0.422535211267606, 0.226415094339623, 0.0943396226415094, 0.367924528301887, 
        0.311320754716981), .Dim = c(4L, 4L), .Dimnames = list(c("A", "B", "C", "D"), c("1", "2", "3", "4")))

d = d %>% 
  data.frame %>%
  rownames_to_column(var = "Groups") %>% 
  pivot_longer(cols = 2:5) %>%
  group_by(Groups) %>% 
  mutate(name = sub("X", "", name) %>% as.numeric(), n = 1:n())

ggplot(data = d) + 
  geom_path(aes(x = name, y = value, group = factor(Groups), color = factor(Groups)), size = 0.7) +
  geom_point(aes(x = name, y = value, color = factor(Groups)), size = 2) +
  geom_text(data = d %>% filter(n == max(n)), aes(x = name, y = value, label = Groups, color = factor(Groups)), nudge_x = 0.2) + 
  labs(x = "Group", y = "P") + 
  theme_bw() +
  theme(legend.position = "none")

For more information check out the following. Here @akrun had made a plot for each graph using matplot: Find proportion of times each character(A,B,C,D) occurs in each column of a list which has 3 datasets


Andy's code works perfectly in the console! However, I originally wanted to run this in a shiny app, but it gives out this error:

`.x` must be a vector, not a `reactiveExpr/reactive/function` object
library(dplyr)
library(tidyr)
library(purrr)
library(ggplot2)

ui<-shinyUI(fluidPage(
  titlePanel(title = h4("proportion graphs", align="center")), sidebarLayout( sidebarPanel( ),
                                                                              
                                                                              mainPanel(
                                                                                # create a uiOutput
                                                                                uiOutput("plots")
                                                                              )
  )
  
))


server<- shinyServer(
  
  function(input, output) {
    #1 Dataset l
    l<- reactive({
      f<- list(`0` = structure(list(X70 = "D", X71 = "C", X72 = "C", X73 = "A", X74 = "B", X75 = "C", X76 = "D", X77 = NA_character_, X78 = "B", X79 = "D", X80 = "C", Q = 1), row.names = 32L, class = "data.frame"), `1` = structure(list(X70 = c("D", "B", "D", "D", "B", "D", "D", "D", "D", "D", "D"), X71 = c("B", "B", "C", "C", "C", NA, "D", "B", "C", "A", "C"), X72 = c("A", "A", "C", "B", "C", "C", "C", "C", "D", "B", NA), X73 = c("B", "C", "C", "B", "C", "D", "A", "B", "C", "C", NA), X74 = c("B", "A", "C", "D", "B", "D", NA, "D", "D", "D", NA), X75 = c("C", "C", "B", "C", "D", "D", "C", "A", "C", "C", "C"), X76 = c("D", "A", "D", "B", "D", "C", "D", "A", "A", "D", "B"), X77 = c("D", "C", "B", "B", "B", "C", "B", "B", "B", "B", "D"), X78 = c("B", "C", "C", "B", "A", "A", "C", "B", "A", "C", NA), X79 = c("C", "C", NA, NA, "D", "A", "A", "A", "D", "A", "D"), X80 = c("B", "A", NA, NA, "B", "C", "B", NA, "B", "C", "A"), Q = c(2, 2, 1, 1, 2, 2, 1, 1, 4, 3, 1)), row.names = c(8L, 10L, 12L, 17L, 25L, 27L, 28L, 33L, 35L, 38L, 45L), class = "data.frame"), `2` = structure(list(X70 = c("D", "D", "D", "B", "D", "C", "D", "D", "D", "D", "D", "D"), X71 = c("A", "B", "C", "C", "A", "A", "C", "B", "C", "C", "D", "B"), X72 = c("D", "C", "D", "A", "A", "C", "D", "C", NA, "D", "C", "B"), X73 = c("B", "D", "D", "C", "B", "D", "D", "D", NA, NA, "C", "A"), X74 = c("D", "C", "B", "D", "C", "B", "C", "C", "B", NA, "C", "D"), X75 = c("B", "C", "C", "C", NA, "C", "B", "C", "C", "C", "B", "C"), X76 = c("A", "D", "D", "D", NA, "D", "D", "A", "D", "D", "D", "D"), X77 = c("B", "B", "D", "B", NA, "B", "D", "B", "B", "B", "B", "B"), X78 = c("C", "D", "C", "B", NA, "D", "C", "C", "B", "D", "C", NA), X79 = c("A", "D", "D", "D", NA, "D", "A", NA, "A", "D", "B", NA), X80 = c(NA, "C", "C", "A", NA, "C", "C", NA, "B", "C", "C", NA), Q = c(2, 3, 3, 1, 3, 1, 2, 2, 1, 2, 2, 1)), row.names = c(4L, 5L, 6L, 11L, 15L, 16L, 21L, 22L, 26L, 37L, 39L, 43L), class = "data.frame"), `3` = structure(list(X70 = c("A", "A", "D", "C", "D", "D", "D", "D", NA, "D", "D", "D"), X71 = c("B", "C", "D", "D", "C", "C", "B", "C", "C", "C", "A", "D"), X72 = c("B", "C", NA, "B", "A", "C", "B", "A", "C", "C", "D", "B"), X73 = c(NA, "C", "C", "A", "D", "C", "A", "A", "D", "B", "D", "B"), X74 = c(NA, "C", "D", "B", "A", "D", NA, "D", "B", "A", "D", "A"), X75 = c(NA, "C", "B", "D", "C", "C", "C", "C", "C", "B", "C", "D"), X76 = c(NA, "D", "A", "B", "A", "D", "D", "D", "D", "D", "D", "D"), X77 = c(NA, "B", "B", "B", "C", "B", "A", "B", NA, "C", "D", "D"), X78 = c(NA, "C", "C", "B", "C", "B", "A", "C", "D", "C", "C", "C"), X79 = c(NA, "D", "D", NA, "B", "D", "A", "D", "A", "D", "D", "A"), X80 = c(NA, "C", "C", NA, "D", "C", "C", "C", "C", "C", "B", "C"), Q = c(2, 2, 2, 2, 4, 2, 4, 4, 4, 3, 3, 2)), row.names = c(2L, 13L, 14L, 18L, 19L, 20L, 29L, 30L, 34L, 36L, 41L, 44L), class = "data.frame"), `4` = structure(list(X70 = c("D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D"), X71 = c("A", NA, "A", "B", "C", "A", "A", "C", "B", "C", "C", "C"), X72 = c("B", "C", "C", "C", NA, "C", "B", "A", "C", "B", NA, "A"), X73 = c(NA, "D", "D", "D", "B", "D", "D", "D", "C", "A", "A", "C"), X74 = c("C", "A", "C", "D", "C", "C", "A", "A", "C", "D", "D", "D"), X75 = c("C", "C", "C", "C", "C", "C", "C", "C", "C", "D", "C", "C"), X76 = c("D", "D", "D", "D", "D", "D", "D", "D", "A", "D", "D", "A"), X77 = c(NA, "B", "D", "B", NA, "B", "B", "B", "C", "D", NA, "C"), X78 = c("C", "C", "C", "C", "A", "A", "C", "A", "C", "C", "C", "C"), X79 = c("D", "D", "A", "D", "D", "A", "D", "D", "A", "D", "C", "C"), X80 = c("C", "C", "C", "C", NA, "C", "C", "C", "C", "C", "C", "A"), Q = c(2, 4, 4, 3, 2, 4, 2, 4, 1, 1, 2, 4)), row.names = c(1L, 3L, 7L, 9L, 23L, 24L, 31L, 40L, 42L, 46L, 47L, 48L), class = "data.frame")) })
    
    
    #2 Vector u
    u <- reactive({
      u <- c("D", "B", "C", "A")
    })
    
    #3 reactive expression to process data
    out <- reactive({
      l <- l()
      u <- u()                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
      
      lapply(l, function(dat) 
        asplit(as.data.frame(t(sapply(dat, function(x) 
          proportions(table(factor(unlist(x), levels = u)))))), 1) ) %>%
        transpose %>%
        map(bind_rows, .id = 'grp')
    })
    
    #4 render plots 
    output$plots <- renderUI({
      
      plots <- function(x){
        d = x %>% 
          as.data.frame() %>%
          tidyr::pivot_longer(!grp) %>%
          dplyr::group_by(name) %>% 
          dplyr::mutate(n = 1:n())
        
        ggplot(data = d) + 
          geom_path(aes(x = grp, y = value, group = factor(name), color = factor(name)), size = 0.7) +
          geom_point(aes(x = grp, y = value, color = factor(name)), size = 2) +
          geom_text(data = d %>% filter(n == max(n)), aes(x = grp, y = value, label = name, color = factor(name)), nudge_x = 0.2) + 
          labs(x = "Group", y = "P", title = "") + 
          theme_bw() +
          theme(legend.position = "none")
      }
      plot_objects <- purrr::map(out, plots)
      
      
    })
    
  } )

shinyApp(ui,server)
AndrewGB
  • 16,126
  • 5
  • 18
  • 49
ujjwal tyagi
  • 493
  • 2
  • 8

1 Answers1

1

So, this is a good opportunity to use purrr::map. You are half way there by applying code to one dataframe.

You can take the code that you have written above and put it into a function.

library(dplyr)
library(tidyr)
library(purrr)
library(ggplot2)

plots <- function(x){
  d = x %>% 
    as.data.frame() %>%
    tidyr::pivot_longer(!grp) %>%
    dplyr::group_by(name) %>% 
    dplyr::mutate(n = 1:n())

ggplot(data = d) + 
  geom_path(aes(x = grp, y = value, group = factor(name), color = factor(name)), size = 0.7) +
  geom_point(aes(x = grp, y = value, color = factor(name)), size = 2) +
  geom_text(data = d %>% filter(n == max(n)), aes(x = grp, y = value, label = name, color = factor(name)), nudge_x = 0.2) + 
  labs(x = "Group", y = "P", title = "") + 
  theme_bw() +
  theme(legend.position = "none")
}

Then, use purrr::map, on your out list. This will return a list of ggplot objects that you can then plot.

plot_objects <- purrr::map(out, plots)

Finally, if you would like to have them all on one page, like in the link you provided, then you could do something like this:

library(ggpubr)

  ggpubr::ggarrange(
  plotlist = plot_objects,
  ncol = 3,
  nrow = 4, 
  labels = names(plot_objects), 
  hjust = -5,
  vjust = 2
)
AndrewGB
  • 16,126
  • 5
  • 18
  • 49
  • This works perfectly! However, I originally wanted to run this in a shiny app. Would you be having any idea why this does not work in a shiny app? I have edited the shiny code in the description. – ujjwal tyagi Jun 15 '21 at 21:37
  • 1
    Great! I'd try looking at this post (there are some other helpful links in there too): https://stackoverflow.com/questions/51325956/how-do-i-display-variable-number-of-ggplots-in-r-shiny-depending-on-input – AndrewGB Jun 15 '21 at 22:08
  • 1
    @ujjwaltyagi Great! Glad that you got it working. You should add an update at the bottom of your question of how you were able to resolve it, as it could help others! – AndrewGB Jun 16 '21 at 19:59