More help with shiny

I'm afraid I need more help with shiny. I feel like a mediocre student who did fine in the intro course on R basics but is struggling with the advanced course on shiny. Hopefully someone on this list will help me work my way through the wonderful world of reactive programming back to the core R I understand.

I have two problems now. The first is that I can't figure out how to debug shiny code. If I run browser() and try to look at a reactive value like my base.list, I get the reactive code that creates the variable, not its contents. If I try to look at base.list, R tells me its not defined.

I also have a problem deleting an item from a list. The dates in launch.list must be later than what the user selects in base.list. It's trivial to delete items from a list in core R but I can't figure out how to do it in shiny.

Any help I get on this would really be appreciated.

library(tidyverse)
library(shiny)
library(lubridate)
library(ggplot2)


ui <- fluidPage(

  titlePanel("What if? Trend"),
  
  sidebarLayout(

    sidebarPanel(
      fileInput("upload.file", "Upload trend data file",
        multiple = FALSE,
        accept = ".csv"),
      uiOutput("base.date.output"),
      uiOutput("launch.date.output"),
      # uiOutput("target.date.output"),
      # textInput("limit","Enter growth limit", value = ""),
      # textInput("study.area","Enter study area name", value = ""),
      # textInput("variable","Enter variable label", value = ""),
    ),
    
    mainPanel(
      # tableOutput("t.input")
      # tableOutput("date.list")
    )
  )
)

server <- function(input, output, session) {
  
  # upload trend data file ----
  t.input <- eventReactive(input$upload.file, {
   read_csv(input$upload.file$datapath)
  })
  #----
  

  # create base date list from lists ----
  list1 <- list(1900,1910,1920,1930,
                1940,1950,1960,1970
                ,1980,1990,2000,2010)
  list1 <- as.data.frame(list1)
  list1 <- t(list1)
  list2 <- list(21.112,27.881,44.051,70.278,
                86.942,136.395,256.782,415.387,
                483.024,545.837,665.865,691.893)
  list2 <- as.data.frame(list2)
  list2 <- t(list2)
  t.input <- reactive(cbind(list1,list2))

  base.list <-reactive(
    {
      req(t.input())
      setNames( as.list(t.input()[,1]),
                NULL)
    }
  )
  #----
  
   launch.list <- reactive(
        base.list()
   )

  # Specify parameters ----
  
  output$base.date.output <- renderUI({
    selectInput("base.date",
                label = "Select base date",
                choices = base.list(),
                selected = "")
  })
  
  output$launch.date.output <- renderUI({
    selectInput("launch.date",
                label = "Select launch date",
                choices = launch.list(),
                selected = "")
  })
  
  reactive(
    date.list <- t.input()
  )
  
  browser()
  
# Define date.options ----        
    reactive(
      if(nchar(as.character(date.list()[1])) == 4) {     # data for years
        date.options <- list(
          date.option = "years",
          date.step = 365,
          date.label = "Year"
        )
      }
      else if (nchar(as.character(date.list()[1])) == 7) {  # data for months
        date.options <- list(
          date.option = "months",
          date.step = 30,
          date.label = "Month"
        )
    } 
    else if (nchar(as.character(date.list()[1])) == 10){ # data for days
        date.options <- list(
          date.option = "days",
          date.step = 1,
          date.label = "Date"
        )
    }
    else {
      date.options <- ""
    }
    )

    # Convert input dates to .R date format

    reactive(
      if(date.option() == "years") {    
        date.R <- make_date(date.list())
        date.lbl <- format(date.R, "%Y")
      }
      else if (date.option() == "months") {
        #   date.str <- as.character(input$date)
        date.R <-make_date(substr(date.list(),1,4),substr(date.list(),6,7))
        date.lbl <- format(date.R, "%Y_%m")
      } 
      else if (date.option() == "days"){                    
        date.R <-make_date(substr(date.list(),1,4),substr(date.list(),6,7),
            substr(date.list(),9,10))
        date.lbl <- format(date.R, "%Y_%m_%d")
      }
    )
    
   reactive(first.date.R <- date.R()[1])
   reactive(last.date.R <-date.R()[length(date.R())])
   
   reactive(
      if (date.option() == "years"){
        first.date.lbl <- format(first.date.R(), "%Y")
        last.date.lbl <- format(last.date.R(), "%Y")      }
      else if (date.option() == "months"){
        first.date.lbl <- format(first.date.R(), "%b %Y")
      }
      else if (date.option() == "days"){
        first.date.lbl <- format(first.date.R(), "%b %d, %Y")
        last.date.lbl <- format(last.date.R(), "%b %d, %Y")
      }
   )
   
     reactive(
       date.interval <- as.numeric(round((date.R()[2] -date.R()[1])/date.step(),0))
     )
# 
# # Compute target date list
#     
#     target.list.R <- data.frame(
#       matrix("",nrow=1,ncol=1))
# 
#     target.list <- data.frame(
#       matrix("",nrow=1,ncol=1))
#     
#     target.list.R[,1] <- last.date.R
#     
#     for(i in seq(from=2, to=51,by=1)) {
#       if (date.option=="years"){
#         target.list.R[,i] <-round_date(target.list.R[,i-1] + (date.interval * date.step), "year") 
#         target.list[i] <- format(target.list.R[i], "%Y")
#       }
#       else if (date.option=="months") {
#         target.list.R[,i] <-round_date(target.list.R[,i-1] + (date.interval * date.step), "month")  
#         target.list[i] <- format(target.list.R[i], "%Y_%m")
#       } 
#       else if (date.option=="days") {
#         target.list.R[,i] <-round_date(target.list.R[,i-1] + (date.interval * date.step), "day")    
#         target.list[i] <- format(target.list.R[i], "%Y_%m_%d")
#       }
#     }
# 
#     target.list <- t(target.list)
#     target.list <- list(target.list)
#     names(target.list) <- "target_list"

}

shinyApp(ui, server)

Where you put your call to browser() matters! If you want to check the content of a reactive expression/value, you generally want to put browser() in a render*() function. In you example, if you want to see the data in base.list() (the parentheses are needed because it is a reactive value), you can put browser() in:

output$base.date.output <- renderUI({
    browser()
    ... # your code is here
})

Now regarding launch.list(), I do not really understand its purpose because it seems to me that its value is exactly the same as base.list()when I look at the "uncommented" code you posted:

  launch.list <- reactive(
    base.list()
  )

Thanks for getting back to me.

Are you saying I need to use a render*() statement if I want to use browser() to check on a reactive/value? I can do that but it seems like there's be easier way to debug my code.

Let me clarify my second question. Let's say I want launch.list() to contain everything in base.list() other than the first element. Deleting a row from a list is trivial in base R, but I don't see how to do it in a reactive statement.

Thanks again.

I think this means that you omit the required brackets to evaluate a reactive.

base.list
base.list()

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

If you have a query related to it or one of the replies, start a new topic and refer back with a link.