0

I have this function which works perfectly well in console. It uses in some data l ,and then processes it to give out some proportion tables in a variable called 'out'. These tables are then plotted using a ggplot package.

library(tidyverse)

### your code
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')


### plot for each table
plot_list = list()
for(i in 1:length(out)){
  # transform data to match previous example
  d = out[[i]] %>% t() %>% as.data.frame() %>% tibble::rownames_to_column(var = "x") %>% janitor::row_to_names(row_number = 1)
  
  # mutate
  d = d %>%
    data.frame() %>%
    pivot_longer(cols = 2:ncol(d)) %>%
    group_by(grp) %>% 
    mutate(name = sub("X", "", name) %>% as.numeric(), n = 1:n())
  
  # plot
  temp_p = ggplot(data = d) + 
    geom_path(aes(x = name, y = value, group = factor(grp), color = factor(grp)), size = 0.7) +
    geom_point(aes(x = name, y = value, color = factor(grp)), size = 2) +
    geom_text(data = d %>% filter(n == max(n)), aes(x = name, y = value, label = grp, color = factor(grp)), nudge_x = 0.2) + 
    labs(x = "Group", y = "P") + 
    theme_bw() +
    theme(legend.position = "none")  
  
  # append
  plot_list = append(plot_list, list(temp_p))
}

plot_list

The code above works perfectly, however when i try to run it in a shiny app , it does not display any graphs. It does not return any error either so i am very confused on what is the issue:-

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

     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({
          
          
          
          plot_list = list()
          for(i in 1:length(out())){
            # transform data to match previous example
            d = out()[[i]] %>% t() %>% as.data.frame() %>% tibble::rownames_to_column(var = "x") %>% janitor::row_to_names(row_number = 1)
            
            # mutate
            d = d %>%
              data.frame() %>%
              pivot_longer(cols = 2:ncol(d)) %>%
              group_by(grp) %>% 
              mutate(name = sub("X", "", name) %>% as.numeric(), n = 1:n())
            
            # plot
            temp_p = ggplot(data = d) + 
              geom_path(aes(x = name, y = value, group = factor(grp), color = factor(grp)), size = 0.7) +
              geom_point(aes(x = name, y = value, color = factor(grp)), size = 2) +
              geom_text(data = d %>% filter(n == max(n)), aes(x = name, y = value, label = grp, color = factor(grp)), nudge_x = 0.2) + 
              labs(x = "Group", y = "P") + 
              theme_bw() +
              theme(legend.position = "none")  
            
            # append
            plot_list = append(plot_list, list(temp_p))
            plot_list[[1]]
          }
        })
        
      } )


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


shinyApp(ui,server)
ujjwal tyagi
  • 493
  • 2
  • 8
  • I think you've misunderstood how `renderUI` works. It should output a list of Shiny `tags`, each of which refers to an output element that is defined elsewhere. In your case, for example, it `renderUI` should output a list of `plotOutput` tags, one for each element of the list. You then need to define a `renderPlot` for each element of the list to actually produce the plot. If the number of elements in the list is not fixed, you may be better off using [modules](https://shiny.rstudio.com/articles/modules.html). – Limey Jun 16 '21 at 06:42
  • ~Incidentally, when I copy-and-paste your code into RStudio, everything from `#2 Vector u` is indented by 3174 spaces and everything above is unindented, though line 13 is 3785 lines long. I'd need to reformat to see all of your code and begin to understand it. I'm not prepared to do that. – Limey Jun 16 '21 at 06:45
  • Also, your sample Shiny code fails with the error `Error in proportions(table(factor(unlist(x), levels = u))) : could not find function "proportions"`. – Limey Jun 16 '21 at 06:54
  • Let me check it whats wrong with the proportions part. If you paste the code in script panel then the formatting works fine – ujjwal tyagi Jun 16 '21 at 07:28

1 Answers1

1

The code works fine for me if I do following changes in ui and server.

In server, change renderUI to renderPlot and return plot_list[[1]] outside the for loop.

output$plots <- renderPlot({
 #...
 #...
 #...
 plot_list[[1]]
})

In ui, change uiOutput("plots") to plotOutput("plots").

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • This works perfectly however the issue is that i originally want to print out multiple plots. In my first code if you would use plot_list instead of plot_list[[1]] , you will get 12 plots(i updated the first code so 12 plots are printed out). I had heard that renderplot only prints 1 plot. The shiny app i am making will always have different number of plots based on what data the user inputs. How can i display these multiple plots? – ujjwal tyagi Jun 16 '21 at 16:50
  • 1
    Yes, renderplot will show only one plot. You can try using facets or use any of these options https://stackoverflow.com/questions/10706753/how-do-i-arrange-a-variable-list-of-plots-using-grid-arrange to combine list of plots into one. – Ronak Shah Jun 17 '21 at 01:34