I am trying to reference the values of a reactive variable. I have included the code I have so far below. I am referring to "output$var1" below. This app selects the dataset and based on that dataset produces another selectInput to select a variable.
I am able to render the text if I directly type dataset$area (the first variable of the rock dataset). I would like to render something like "dataset$selvar". Is there a way to do this?
library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("dataset", label = "Dataset", choices =c("rock","pressure","cars")),
numericInput(inputId = "obs",
label = "Number of observations to view:",
value=10)
),
mainPanel(
verbatimTextOutput("summary"),
tableOutput("table"),
selectInput("inSelect","Select variable", c("Item A", "Item B")),
textOutput("var1")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
datasetInput<-reactive({
switch(input$dataset,
"rock"=rock,
"pressure"=pressure,
"cars"=cars
)
})
output$summary<- renderPrint({
dataset<- datasetInput()
summary(dataset)
})
output$table<- renderTable({
head(datasetInput(), n=input$obs)
})
observe({
dataset<- datasetInput()
varlist<-colnames(dataset)
updateSelectInput(session,"inSelect",
label="Select variable",
choices=varlist,
selected=head(varlist,1)
)
selvar<-updateSelectInput(session,"inSelect",
label="Select variable",
choices=varlist,
selected=head(varlist,1)
)
output$var1<-renderText({
dataset$area
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
When I try dataset$selvar I get "error i ncat: argument 1 (type 'environment') cannot be bandled by 'cat'
Remove the second updateSelectInput from your observer, move your renderText outside of the observer. and inside the renderText use datasetInput()[[input$inSelect]] to display the select column from the selected dataset.
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("dataset", label = "Dataset", choices = c("rock", "pressure", "cars")),
numericInput(
inputId = "obs",
label = "Number of observations to view:",
value = 10
)
),
mainPanel(
verbatimTextOutput("summary"),
tableOutput("table"),
selectInput("inSelect", "Select variable", c("Item A", "Item B")),
textOutput("var1")
)
)
)
server <- function(input, output, session) {
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"pressure" = pressure,
"cars" = cars
)
})
output$summary <- renderPrint({
dataset <- datasetInput()
summary(dataset)
})
output$table <- renderTable({
head(datasetInput(), n = input$obs)
})
observe({
dataset <- datasetInput()
varlist <- colnames(dataset)
updateSelectInput(session, "inSelect",
label = "Select variable",
choices = varlist,
selected = varlist[[1]]
)
})
output$var1 <- renderText({
datasetInput()[[input$inSelect]]
})
}
# Run the application
shinyApp(ui = ui, server = server)
#>
#> Listening on http://127.0.0.1:5275
Related
I'm exploring shiny and I'm trying to do some app that does the following:
Let the user choose between two (or more) different data.frames (in my example I use mtcars and iris but I'm planning to use some self-made data.frames.
Select some X and Y variables according to the data.frame selected
Plot a simple x-y scatterplot
Code below:
df_list <- list(cars= mtcars, iris= iris)
ui <- fluidPage(
titlePanel("Simple app"),
sidebarLayout(
sidebarPanel(
selectInput("data", "Choose a database",
choices=ls(df_list), selected=ls(df_list[1])),
selectInput("xcol", "Variable X", names(data)),
selectInput("ycol", "Variable Y", names(data))),
mainPanel(
plotOutput(outputId = "plot")
)
)
)
server <- function(input, output) {
selectedData <- reactive( {
data[, c(data$xcol, data$ycol)]
})
output$plot <- renderPlot({plot(selectedData())})
}
shinyApp(ui, server)
I feel I have two problems. The first one is pretty obvious since I can't make the app displays variables according to the data.frame selected. Second one is that I feel I'm missing something in my server function (I guess that's related with my first problem) so no plot is displayed.
Any help will be much appreciated.
You had a few issues. The following should work.
df_list <- list("mtcars", "iris")
ui <- fluidPage(
titlePanel("Simple app"),
useShinyjs(),
sidebarLayout(
sidebarPanel(
selectInput("data", "Choose a database",
choices=df_list, selected=df_list[[1]]),
selectInput("xcol", "Variable X", c()),
selectInput("ycol", "Variable Y", c())),
mainPanel(
plotOutput(outputId = "plot")
,DTOutput("t1")
)
)
)
server <- function(input, output, session) {
mydata <- eventReactive(input$data, {
get(input$data)
})
observeEvent(input$data, {
req(mydata())
choices <- names(mydata())
updateSelectInput(session,"xcol",choices = choices, selected=choices[1])
updateSelectInput(session,"ycol",choices = choices, selected=choices[2])
}, ignoreNULL = FALSE)
output$t1 <- renderDT({mydata()})
output$plot <- renderPlot({
req(mydata(),input$xcol,input$ycol)
if (is.null(mydata()) | !(input$xcol %in% colnames(mydata())) | !(input$ycol %in% colnames(mydata())) ) {
return(NULL)
} else{
selected_df <- mydata() %>% select(input$xcol, input$ycol)
plot(selected_df)
}
})
}
shinyApp(ui, server)
in Shiny I simply want to select which variable of a dataframe shall be plotted and I do not want to have to type all the variable names in the server switch part. Here is what I do:
ui <- fluidPage(
titlePanel("Hello World!"),
sidebarLayout(
sidebarPanel(
selectInput("variable", "Choose a variable:",
# choices = c("cyl", "mpg")),
choices = names(mtcars)),
),
mainPanel(
plotOutput(outputId = "BarPlot"),
)
)
)
server <- function(input, output) {
datasetInput <- reactive({
switch(input$variable,
"cyl" = mtcars[,"cyl"],
"mpg" = mtcars[,"mpg"])
})
output$BarPlot <- renderPlot({
x <- datasetInput()
barplot(table(x))
})
}
Instead of
switch(input$variable,
"cyl" = mtcars[,"cyl"],
"mpg" = mtcars[,"mpg"])
can I do something like
choices = mtcars[,get(choices)]
to cover all choices without having to type them one by one?
One approach is to use varSelectInput and pass the data frame as data (it will include all column names as the choices). Then you can extract the selected column from mtcars through mtcars[[input$variable]] in your example:
library(shiny)
ui <- fluidPage(
titlePanel("Hello World!"),
sidebarLayout(
sidebarPanel(
varSelectInput("variable",
"Choose a variable:",
data = mtcars),
),
mainPanel(
plotOutput(outputId = "BarPlot"),
)
)
)
server <- function(input, output) {
datasetInput <- reactive({
mtcars[[input$variable]]
})
output$BarPlot <- renderPlot({
x <- datasetInput()
barplot(table(x))
})
}
shinyApp(ui, server)
I am new to R Shiny. I am attempting to create an app that allows a user to subset a data.frame based on multiple variables and then see the resulting data.
Here is a small example data set:
iter,wave,apples
1,1,600
1,1,500
1,1,400
1,2,300
1,2,200
1,2,100
2,1,1000
2,1,1100
2,1,1200
2,2,1300
2,2,1400
2,2,1500
3,1,1100
3,1,2200
3,1,3300
3,2,4400
3,2,5500
3,2,6600
I would like the user to be able to specify the value of iter and of wave and see the resulting data.
Here is my attempt at the Shiny code. I realize I must be making several silly mistakes.
Edit
Here is my revised code. The end result now comes pretty close to what I want. The sidebar is still not being displayed perfectly.
library(shiny)
setwd('C:/Users/mark_/Documents/simple_RShiny_files/explore')
apple.data <- read.csv('subset_data_based_on_multiple_variables.csv',
header = TRUE, stringsAsFactors = FALSE)
ui <- fluidPage(
titlePanel("Subsetting Apple Dataset"),
sidebarLayout(
sidebarPanel(
uiOutput("codePanel")
),
mainPanel(
tableOutput("view")
)
),
selectInput("codeInput", inputId ="data1", label = "Choose Iter", choices = unique(apple.data$iter)),
selectInput("codeInput", inputId ="data2", label = "Choose Wave", choices = unique(apple.data$wave))
)
server <- function(input, output) {
output$codePanel <- renderUI({
})
dataset <- reactive({
subset(apple.data, (iter == input$data1 & wave == input$data2))
})
output$view <- renderTable(dataset())
}
shinyApp(ui = ui, server = server)
The output
The problem is that both selectInputs have the same inputId. This works:
library(shiny)
apple.data <- data.frame(
iter = c(1L,1L,1L,1L,1L,1L,2L,2L,2L,2L,2L,
2L,3L,3L,3L,3L,3L,3L),
wave = c(1L,1L,1L,2L,2L,2L,1L,1L,1L,2L,2L,
2L,1L,1L,1L,2L,2L,2L),
apples = c(600L,500L,400L,300L,200L,100L,1000L,
1100L,1200L,1300L,1400L,1500L,1100L,2200L,3300L,4400L,
5500L,6600L)
)
ui <- fluidPage(
titlePanel("Subsetting Apple Dataset"),
sidebarLayout(
sidebarPanel(
selectInput("codeInput1", label = "Choose Iter", choices = unique(apple.data$iter)),
selectInput("codeInput2", label = "Choose Wave", choices = unique(apple.data$wave))
),
mainPanel(
tableOutput("view")
)
)
)
server <- function(input, output) {
dataset <- reactive({
return(subset(apple.data, (iter == input$codeInput1 & wave == input$codeInput2)))
})
output$view <- renderTable(dataset())
}
shinyApp(ui = ui, server = server)
I am new to Shiny and learning it's features. Using the mtcars data, I am trying to create a plot whose axis will alter upon user input. When I run the app, I am getting error telling me the "x and y lengths are not the same", so it appears that "data" specified in the plot function is not receiving the mtcars dataframe columns. The plot works property if I replace "data" with any of the columns listed in the server function.
shinyUI(navbarPage("My Application",
tabPanel("Component 1"),
tabPanel("Component 2"),
tabPanel("Component 3",
fluidPage(
fluidRow(
column(4,
"Sidebar",
helpText("This is my longer help text help text."),
selectInput("var",
label = "Choose a variable to display",
choices = c("mpg", "disp", "hp", "qsec"),
selected = "A")
),
column(8,
#style = "background-color:#4d3a7d;",
"Main",
textOutput("selected_var"),
plotOutput("plot1")
)
)
)
),
navbarMenu("More",
tabPanel("Sub-Component A"),
tabPanel("Sub-Component B"))
))
shinyServer(function(input, output) {
data <- reactive({
if("mpg" %in% input$var) return(mtcars$mpg)
if("disp" %in% input$var) return(mtcars$disp)
if("hp" %in% input$var) return(mtcars$hp)
if("qsec" %in% input$var) return(mtcars$qsec)
})
output$selected_var <- renderText({
paste("you have selected", input$var)
})
output$plot1 <- renderPlot({
plot(mtcars$wt, data)
})
})
I figured it out - "data" should have been "data()".
We could also use switch instead of if. Also, in the selected in selectInput, it could be one of the choices. Not sure where "A" is defined
library(shiny)
-ui
ui <- navbarPage("My Application",
tabPanel("Component 1"),
tabPanel("Component 2"),
tabPanel("Component 3",
fluidPage(
fluidRow(
column(4,
"Sidebar",
helpText("This is my longer help text help text."),
selectInput("var",
label = "Choose a variable to display",
choices = c("mpg", "disp", "hp", "qsec"),
selected = "mpg")
),
column(8,
#style = "background-color:#4d3a7d;",
"Main",
textOutput("selected_var"),
plotOutput("plot1")
)
)
)
),
navbarMenu("More",
tabPanel("Sub-Component A"),
tabPanel("Sub-Component B"))
)
-server
server <- function(input, output) {
data <- reactive({
switch(input$var,
mpg = mtcars$mpg,
dist = mtcars$disp,
hp = mtcars$hp,
qsec = mtcars$qsec
)
})
output$selected_var <- renderText({
paste("you have selected", input$var)
})
output$plot1 <- renderPlot({
plot(mtcars$wt, data(), xlab = "wt", ylab = input$var)
})
}
shinyApp(ui = ui, server = server)
-output
I have reactive data react$data, and I have two inputs input$chosencolumn, input$chosenrows
With the reactive dataset, how would I be able to specify rows I want like a data.frame where you do data[data$chosencolumn == chosenrows,]
Reproducible example:
server.R
### Start of Shiny server
shinyServer(function(input, output, session) {
reactdata <- reactiveValues()
observe({
if(is.null(input$fileinput)){return(NULL)}
else{reactdata$inputdata <- read.xlsx(input$fileinput$datapath, header=T, sheetIndex = 1)}
})
output$selectsamples <- renderUI({
if(is.null(input$fileinput)){return(NULL)}
selectInput("selectsamples",
label = h5("Samples"), choices = colnames(reactdata$inputdata),
selected="Sample")
})
output$sampleselected <- renderUI({
if(is.null(input$fileinput)){return(NULL)}
selectInput("sampleselected",
label = h5("sampleselected"), choices = unique(as.character(reactdata$inputdata[,input$selectsamples])),
selected="B")
})
output$selectdilutions <- renderUI({
if(is.null(input$fileinput)){return(NULL)}
selectInput("selectdilutions",
label=h5("Select Dilutions"),
choices = colnames(reactdata$inputdata),
selected="Dilution")
})
reactdata1 <- reactiveValues()
observe({
reactdata1$datatable1 <- datatable(reactdata$inputdata,
rownames = TRUE,
options = list(pageLength = 100, dom = 'tip'))
})
output$datatable1 <- renderDataTable({
reactdata1$datatable1
})
})
ui.R
require(shiny)
require(devtools)
require(grDevices)
require(xlsx)
require(DT)
shinyUI(fluidPage(
navbarPage("",inverse = FALSE,
tabPanel("Analyse")),
titlePanel(""),
fluidRow(
column(3,
wellPanel(
fileInput("fileinput", label = h5("Input file")),
uiOutput("selectsamples"),
uiOutput("sampleselected"),
uiOutput("selectdilutions")
)),
column(9,
fluidRow(
wellPanel(
uiOutput("sample1"),
dataTableOutput("datatable1"))
)))
)
)
I would like to change reactdata1$datatable1 so that it only includes rows of data chosen by the sample selected (i.e. the value that input$sampleselected is chosen as).
So, something like reactdata1$datatable1[input$selectsamples == input$sampleselected,]
An example dataset is here:
Dropbox link to excel file
Here's a general example where you subset a reactive data.frame based on dynamically entered user input:
require(shiny)
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("dataset", "Choose a dataset:",
choices = c("rock", "pressure", "cars","DNase","iris")
),
selectizeInput(
'colName', 'Select Column: ', list(), multiple = TRUE
),
selectizeInput(
'rowName', 'Select Rows', list(), multiple = TRUE
)
),
mainPanel(
tableOutput('tbl')
)
) #end sidebar layout
))
server <- shinyServer(function(input, output, session) {
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"pressure" = pressure,
"cars" = cars,
"DNase"=DNase,
"iris"=iris)
})
# Update UI
observe({
updateSelectizeInput(session, "colName", choices = colnames( datasetInput() ))
updateSelectizeInput(session, "rowName", choices = rownames( datasetInput() ))
})
# Create reactive data by subseting the reactive dataset
r1 <- reactive({
v <- input$colName %in% colnames(datasetInput())
if( sum(v == FALSE) > 0) return() # Check for missmatching datasetInput names and column names
if(is.null(input$colName) || is.null(input$rowName)) return() # None selected, return empty
# Subset data
datasetInput()[as.numeric(input$rowName), input$colName, drop=FALSE]
})
output$tbl <- renderTable({
r1()
})
})
shinyApp(ui, server)