-1

I have created a shiny app where the user inputs some data and then the data is splitted into groups of rows like this based on a coloumn. This gives me different groups of data sets. The number of groups of data sets will always be different as it depends on what the user inputs in the coloumn which is being used to split the data in groups of rows. I know how to display single datasets but how can i display these groups of datasets which come as outputs in different tables? I also made a short video which explains visually what i need help with

Server:-

library(shiny)
data(iris)
shinyServer(
  
  function(input, output) {
    
    output$data <- renderUI({
      splitDFs<- split(iris, iris$Species)
      splitRenders <- lapply(splitDFs, renderTable)
      return(splitRenders)
      # head(iris)
      
    })
    

  }
)

UI:-

library(shiny)
shinyUI(fluidPage(
  titlePanel(title = h4("Iris Dataset", align="center")),
  sidebarLayout(
    sidebarPanel(
    ),
    
    mainPanel(
      uiOutput("data"),
                  
      )
      
    )
    
  ))

enter image description here

Same table again displayed

enter image description here

Damon Kutt
  • 41
  • 4

1 Answers1

1

You can look into uiOutput and renderUI. These allow you to pass dynamic render objects or lists of objects. You'd have uiOutput("someName") in your ui, and then a output$someName <- renderUI(...) in your server.

In the renderUI, you perform the split. You then put each of the result into a renderTable, then return the list of renderTable objects.

Some additional reading on things like this:

Unknown number of tables to be presented in Shiny

Output N tables in Shiny

Dynamic Number of Output Elements

Shiny Example with Dynamic Number of Plots

Edit: Your ui is fine, you can use this as your server:

output$data <- renderUI({
    splitDFs<- split(iris, iris$Species)
    
    splitRenders <- lapply(1:length(splitDFs), function(x) renderTable(splitDFs[[x]]))

    return(splitRenders)
    
  })

The problem with the previous version was that lapply renderTable for some reason was not directly getting at the elements of splitDFs*, it was just picking up the last one each time. This explicitly extracts the individual split dataframes and properly builds the render, so it should work now.

  • This is strange because lapply works properly in other scenarios, e.g. when the function is print. It might be something like ggplot, where the dataframe is passed in but not evaluated till the end, so the renderTable gets overwritten with the latest one.
Aqeel Padaria
  • 231
  • 3
  • 7
  • Is this is what you mean? output$Domain_split <- renderUI({ cf<- control(); cf_scorable <- cf[cf$IsScorable == TRUE,]#this is the data Domainlist<-(cf[cf$IsScorable == TRUE,c('Domain')])#This is the coloumn on the basis of which i want to split return(renderTable(split(data.frame(cf_scorable),as.factor(Domainlist)))) }) – Damon Kutt May 29 '21 at 11:58
  • 1
    Your comment is formatted a bit weirdly, so it all glomps into a single line, but from the looks of it you're still just returning a single renderTable. I assume the split function returns a list of dataframes? You want to take that list, and put each element inside a renderTable. So now you have a list of renderTables - THAT is what you return. – Aqeel Padaria May 29 '21 at 18:22
  • 1
    Just checked, it does. So you could do: `splitDFs <- split(...)`, then `splitRenders <- lapply(splitDFs, renderTable)`, then `return(splitRenders)` – Aqeel Padaria May 29 '21 at 18:25
  • 1
    (The ... is just because I didn't want to copy the parameters for the split function, you'll obviously want to put in the appropriate parameters there) – Aqeel Padaria May 29 '21 at 18:26
  • I made a small app by what you suggested . i have edited it in the description. But it gives a strange output. it gives me the same table 3 times – Damon Kutt May 31 '21 at 18:47
  • Yeah, that code needs some tweaks, actually. lapply doesn't work directly on renderTable. I've pasted the updated code into an edit in my main answer. – Aqeel Padaria Jun 02 '21 at 04:49
  • I also figured out another way to do it but then i stumbled upon another problem. Can you check this out ? https://stackoverflow.com/questions/67793957/unable-to-use-apply-function-inside-an-lapply-function-in-a-shiny-app – Damon Kutt Jun 02 '21 at 08:02