Combining renderUI, dataTableOutput, renderDataTable, and reactive

I would like to have the DT::renderDataTable inside the renderUI and then have the output of the renderUI used in the reactive.

This is what I'm doing:

suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(plotly))
suppressPackageStartupMessages(library(shiny))


#data.frames to be used in the server
set.seed(1)
coordinate.df <- data.frame(coordinate_id = paste0("c", 1:1000),x = rnorm(1000), y = rnorm(1000), stringsAsFactors = F)
feature.df <- data.frame(coordinate_id = rep(paste0("c", 1:1000), 10), feature_id = rep(paste0("f", 1:10), 1000), value = rnorm(10*1000), stringsAsFactors = F)
feature.rank.df <- feature.df %>% dplyr::select(feature_id) %>% unique() %>% dplyr::mutate(rank=sample(1:10,10,replace = F)) %>% dplyr::arrange(rank)

feature.color.vec <- c("lightgray","darkred")

server <- function(input, output)
{

  output$feature.idx <- renderUI({
    output$feature.table <- DT::renderDataTable(feature.rank.df, server = FALSE, selection = "single")
    DT::dataTableOutput("feature.table")
  })

  feature.plot <- reactive({
    if(!is.null(input$feature.idx)){
      feature.id <- feature.rank.df$feature_id[input$feature.idx]
      plot.title <- feature.id
      plot.df <- suppressWarnings(feature.df %>%
                                    dplyr::filter(feature_id == feature.id) %>%
                                    dplyr::left_join(coordinate.df,by = c("coordinate_id"="coordinate_id")))
      feature.plot <- suppressWarnings(plotly::plot_ly(marker=list(size=3),type='scatter',mode="markers",color=plot.df$value,x=plot.df$x,y=plot.df$y,showlegend=F,colors=colorRamp(feature.color.vec)) %>%
                                        plotly::layout(title=plot.title,xaxis=list(zeroline=F,showticklabels=F,showgrid=F),yaxis=list(zeroline=F,showticklabels=F,showgrid=F)) %>%
                                        plotly::colorbar(limits=c(min(plot.df$value,na.rm=T),max(plot.df$value,na.rm=T)),len=0.4,title="Value"))
    }
    feature.plot
  })

  output$outPlot <- plotly::renderPlotly({
    feature.plot()
  })
}


ui <- fluidPage(
  titlePanel("Results Explorer"),
  sidebarLayout(
    sidebarPanel(
      uiOutput("feature.idx")
    ),

    mainPanel(
      plotly::plotlyOutput("outPlot")
    )
  )
)

shinyApp(ui = ui, server = server)

It does load the feature.rank.df data.frame but it then prints this error message to the main panel:

Error: no applicable method for 'plotly_build' applied to an object of class "c('reactiveExpr', 'reactive')"

And nothing gets plotted upon row selection in the table in the side panel.

Any idea what the solution is?

section 2.1.1 https://rstudio.github.io/DT/shiny.html rows selection.
you can select rows from a datatable (by its unique id) , not by a renderUI that contains it.

suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(plotly))
suppressPackageStartupMessages(library(shiny))


#data.frames to be used in the server
set.seed(1)
coordinate.df <- data.frame(coordinate_id = paste0("c", 1:1000),x = rnorm(1000), y = rnorm(1000), stringsAsFactors = F)
feature.df <- data.frame(coordinate_id = rep(paste0("c", 1:1000), 10), feature_id = rep(paste0("f", 1:10), 1000), value = rnorm(10*1000), stringsAsFactors = F)
feature.rank.df <- feature.df %>% dplyr::select(feature_id) %>% unique() %>% dplyr::mutate(rank=sample(1:10,10,replace = F)) %>% dplyr::arrange(rank)

feature.color.vec <- c("lightgray","darkred")

server <- function(input, output)
{
  
  output$feature.idx <- renderUI({
    output$feature.table <- DT::renderDataTable(feature.rank.df, server = FALSE, selection = "single")
    DT::dataTableOutput("feature.table")
  })
  
  feature.plot <- reactive({
    if(!is.null(input$feature.table_rows_selected)){
      feature.id <- feature.rank.df$feature_id[input$feature.table_rows_selected]
      plot.title <- feature.id
      plot.df <- suppressWarnings(feature.df %>%
                                    dplyr::filter(feature_id == feature.id) %>%
                                    dplyr::left_join(coordinate.df,by = c("coordinate_id"="coordinate_id")))
      feature.plot <- suppressWarnings(plotly::plot_ly(marker=list(size=3),type='scatter',mode="markers",color=plot.df$value,x=plot.df$x,y=plot.df$y,showlegend=F,colors=colorRamp(feature.color.vec)) %>%
                                         plotly::layout(title=plot.title,xaxis=list(zeroline=F,showticklabels=F,showgrid=F),yaxis=list(zeroline=F,showticklabels=F,showgrid=F)) %>%
                                         plotly::colorbar(limits=c(min(plot.df$value,na.rm=T),max(plot.df$value,na.rm=T)),len=0.4,title="Value"))
    } else{
      feature.plot <- NULL
    }
    feature.plot
  })
  
  output$outPlot <- plotly::renderPlotly({
    feature.plot()
  })
}


ui <- fluidPage(
  titlePanel("Results Explorer"),
  sidebarLayout(
    sidebarPanel(
      uiOutput("feature.idx")
    ),
    
    mainPanel(
      plotly::plotlyOutput("outPlot")
    )
  )
)

shinyApp(ui = ui, server = server)
1 Like

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