I have n number of sliderInput objects in my Shiny app, each with an ID given by df$category[n]. These sliderInput objects have starting values given by df$value[n]. I would like to define a new reactive data frame where the values are given by the slider values. The code below works for the case when you call the sliderInput objects explicitly.
How to I call the sliderInput objects indirectly?
df <- data.frame(category = c("Coffee", "Grinder", "Machine"),
unitcost = c(1, 3, 8),
value = round(runif(3, min = 0, max = 50)))
ui <- ...
sliderInput(df$category[1], paste(df$category[1]),
value = df$value[1],
min = 0,
max = maximum),
sliderInput(df$category[2], paste(df$category[2]),
value = df$value[2],
min = 0,
max = maximum),
sliderInput(df$category[3], paste(df$category[3]),
value = df$value[3],
min = 0,
max = maximum)
...
server <- function(input, output) {
...
new_df <- reactive({
return(as_tibble(df) %>%
mutate(value = c(input$Coffee, input$Grinder, input$Machine))
)
...
})
The function get() should allow me to call objects indirectly but this isn't working for me. I tried the below without success
new_df <- reactive({
return(as_tibble(df) %>%
mutate(value = c(get(paste0("input$",df$category[1])),
get(paste0("input$",df$category[2])),
get(paste0("input$",df$category[3]))
)
You can use reactiveValuesToList() from shiny. I would avoid using get(), which can be difficult in shiny due to the environments created through reactivity and the fact that the server component is its own environment in addition to the global environment. Also, paste isn't needed and because [ is vectorized you can pass it a list instead of using c() and calling it multiple times. You also don't need to explicitly call return(), as reactive() works just like a function and will return automatically.
server <- function(input, output) {
new_df <- reactive({
as_tibble(df) %>%
mutate(value = reactiveValuesToList(input)[df$category[1:3]])
})
}
You could also just use:
server <- function(input, output) {
new_df <- reactive({
as_tibble(df) %>%
mutate(value = reactiveValuesToList(input)[category])
})
}
This works because you are in the pipe sequence and can obtain the value of category without referencing df.
UPDATE
Here is a complete working example, including a rendering of the table to validate accuracy.
library(magrittr)
library(tibble)
library(dplyr)
library(shiny)
df <- data.frame(category = c("Coffee", "Grinder", "Machine"),
unitcost = c(1, 3, 8),
value = round(runif(3, min = 0, max = 50)))
ui <- fluidPage(sliderInput(df$category[1], paste(df$category[1]),
value = df$value[1],
min = 0,
max = 1000),
sliderInput(df$category[2], paste(df$category[2]),
value = df$value[2],
min = 0,
max = 1000),
sliderInput(df$category[3], paste(df$category[3]),
value = df$value[3],
min = 0,
max = 1000),
tableOutput("table"))
server <- function(input, output) {
new_df <- reactive({
as_tibble(df) %>%
mutate(value = reactiveValuesToList(input)[category])
})
output$table <- renderTable({new_df()})
}
shinyApp(ui,server)

get() will return the one object named "input$Coffee" (for example) that can be found in the current environment, not the value of the input structure with id such as input$Coffee.
You shall try the following code to replace yours:
new_df <- reactive({
return(as_tibble(df) %>%
mutate(value = c(get("input")[[ df$category[1] ]],
get("input")[[ df$category[2] ]],
get("input")[[ df$category[3] ]]
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With