2
votes

I am writing a Shiny App, part of which includes the user inputting text to mimic R code and the app itself picking out certain words from this input to print a vector related to what the user is calling. However, when I try to input any words into the app and press the action button, it will crash the program and return the error: Warning: Error in [.default: invalid subscript type 'list', with an indication that it is in the observeEvent handler. There is a list within the event, but I unlist it at one point as I cannot work with it in the way I intended otherwise, and I am not sure how this is interfering with or crashing the app. I provided the relevant part of the app code below:

 library(shiny)
 library(stringr)

 site <- c(rep("A", 5), rep("B", 5), rep("C", 5), rep("D", 5))
 my.num <- 1:20
 temp <- rnorm(20, 5, 1)
 growth <- 5*temp + rnorm(20, 0, 2)

  my.data <- data.frame(site = site, my.num = my.num, temp = temp, growth = growth)

 ui <- pageWithSidebar(
     headerPanel('Data Wrangler'), 
        sidebarPanel(
       p("It is important to use the right commands to be able to properly format
           your data. Let's see what it looks like when we try to use the combine function (c) tp join our variables
            instead, for instance:"),
   textInput("var.com", "Combine several of the variables using c():", NULL),
    actionButton("go6", "GO!")
   ), 
  mainPanel(
    textOutput("display2")
  ))

 server <- function(input, output, session) {

 buttonValue <- reactiveValues(go6=FALSE)

   observeEvent(input$go6, {

     isolate({
       buttonValue$go6 = TRUE
     })

     games <- names(my.data)
     tofind <- paste(games, collapse="|")

     cominput <- str_extract_all(input$var.com, tofind)

     printables <- NULL


    for (i in 1:length(cominput)){


       printables[i] <- c(my.data[cominput[i]])
       printables

     }

     working <- unlist(printables)




      output$display2 <- renderText(
      is.not.null <- function(x) !is.null(x),

      if (is.not.null(working)) {
        print(working)
      } else {
        print("Sorry, this is incorrect; check your signage.")
      }
    )





    session$onSessionEnded({
     stopApp
   }) 

 })
 }

 shinyApp(ui = ui, server = server)

All of this works as intended without the Shiny elements incorporated, so it is something to do with the Shiny reactivity not handling some element of this. Any help would be appreciated!

Edit: Below I included a screenshot of some of the expected output, using the code before it is passed to Shiny. It should be able to take any of the variable names ("site," "temp," "growth") etc., and smash them together and print them as a long vector, to simulate what would happen if you just tried to combine them with c(). The demo code for this output is as follows:

   library(stringr)

   site <- c(rep("A", 5), rep("B", 5), rep("C", 5), rep("D", 5))
   my.num <- 1:20
   temp <- rnorm(20, 5, 1)
   growth <- 5*temp + rnorm(20, 0, 2)

   my.data <- data.frame(site = site, my.num = my.num, temp = temp, growth = growth)

dubbo <- c("temp", "my.num")
 games <- names(my.data)

   tofind <- paste(games, collapse="|")

    secondinput <- str_extract_all(dubbo, tofind)
    printables <- NULL


   for (i in 1:length(secondinput)){


     printables[i] <- c(my.data[secondinput[[i]]])
     printables

    }

  susus <- NULL

   susus <- unlist(printables)
    susus

Expected Output: enter image description here

1
Your ui has some formatting error...maybe forgetting sidebarPanel()? - phalteman
Oops, sorry, I had accidentally deleted that while pasting the code in to here because there were other things in the app/ui that I didn't include. This was not an issue, though. - emc123
Part of the problem is that cominput is a list that you're not indexing correctly with this line: c(my.data[cominput[i]]). But what behaviour do you want to see? Can you provide an expected input and output? - phalteman
Oh, yes, I see - I think originally I had it planned to be passed as a vector (which wasn't working) and I did not change it properly when I worked it into a list. It still does not seem to be doing what I am hoping it will do. I added an example code, without Shiny, of what I want it to print. "dubbo" acts as the string/text that the user would input in the actual app. - emc123

1 Answers

2
votes

You are missing some error handling after str_extract_all and you were trying to access the elements of cominput (which is a list()) in a wrong way.

Does this do what you expect?:

library(shiny)
library(stringr)

site <- c(rep("A", 5), rep("B", 5), rep("C", 5), rep("D", 5))
my.num <- 1:20
temp <- rnorm(20, 5, 1)
growth <- 5 * temp + rnorm(20, 0, 2)

my.data <-
  data.frame(
    site = site,
    my.num = my.num,
    temp = temp,
    growth = growth
  )

ui <- pageWithSidebar(
  headerPanel('Data Wrangler'),
  sidebarPanel(
    p(
      "It is important to use the right commands to be able to properly format
           your data. Let's see what it looks like when we try to use the combine function (c) tp join our variables
            instead, for instance:"
    ),
    textInput("var.com", "Combine several of the variables using c():", NULL),
    actionButton("go6", "GO!")
  ),
  mainPanel(textOutput("display2"))
)

server <- function(input, output, session) {
  buttonValue <- reactiveValues(go6 = FALSE)

  observeEvent(input$go6, {
    isolate({
      buttonValue$go6 = TRUE
    })

    games <- names(my.data)
    tofind <- paste(games, collapse = "|")

    cominput <- str_extract_all(input$var.com, tofind)

    printables <- list(NULL)

    if (identical(cominput, list(character(0)))) {
      working <- NULL
    } else {
      for (i in 1:length(unlist(cominput))) {
        printables[i] <- c(my.data[cominput[[1]][i]])
      }
      working <- unlist(printables)
    }

    output$display2 <- renderText(if (!is.null(working)) {
      print(working)
    } else {
      print("Sorry, this is incorrect; check your signage.")
    })

    session$onSessionEnded({
      stopApp
    })

  })
}

shinyApp(ui = ui, server = server)