How to select variables from different data.frames in shiny? - r

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)

Related

Shiny: How can I loop thru variable names in the ui selectInput choices in the server datasetInput switch?

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)

Shiny with three inputs of selecting variable, its levels and adding other columns

From the code, renderUI in server is disconnected to the main variable selection, so as print textOutput() to main pannel.
I'm trying to build a shiny app has three inputs at the sidebar of
selecting a main variable
the levels of the selected main variable to choose(multiple)
options of adding columns, and then print selected data at the main panel
for example, with iris,
I choose Species
level should show options of "setosa" "versicolor" "virginica" but which is not showing
I can add other columns
But the selected rows and columns are not printed at the main panel
data <- iris
ui <- fluidPage(
titlePanel("Data selection"),
sidebarLayout(
sidebarPanel(
selectizeInput("show_vars", "Main column:",
choices = colnames(data), multiple = FALSE),
uiOutput("category1"),
selectInput("add_col", "Add columns to display", names(data), multiple = TRUE)
),
mainPanel(
textOutput("selected")
)
)
)
server <- function(input, output,session) {
output$category1 <- renderUI({
selectizeInput('cat1', 'Levels from main column', choices = levels(input$show_vars), multiple = TRUE)
})
df_subset <- eventReactive(input$cat1,{
columns = names(data)
if(input$cat1=="All") {df_subset <- data}
else{df_subset <- data[data$Category1 == input$cat1, columns]}
})
output$selected <- renderText({ df_subset() })
}
shinyApp(ui, server)
Perhaps you are looking for this
data <- iris
ui <- fluidPage(
titlePanel("Data selection"),
sidebarLayout(
sidebarPanel(
selectInput("show_vars", "Main column:",
choices = colnames(data), multiple = FALSE),
uiOutput("category1"),
selectInput("add_col", "Add columns to display", names(data), multiple = TRUE)
),
mainPanel(
DTOutput("selected")
)
)
)
server <- function(input, output,session) {
output$category1 <- renderUI({
req(input$show_vars)
selectInput('cat1', 'Levels from main column', choices = c('All',levels(data[,input$show_vars])), multiple = TRUE)
})
df_subset <- reactive({
req(input$cat1,input$add_col)
columns <- names(data) %in% input$add_col
if(input$cat1=="All") {dfsubset <- data[,columns]}
else {dfsubset <- data[data[,input$show_vars] == input$cat1, columns]}
dfsubset <- as.data.frame(dfsubset)
})
output$selected <- renderDT({ df_subset() })
}
shinyApp(ui, server)

Subset data in R Shiny using Multiple Variables

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)

How do I complete this code for Shiny App?

I am struggling in writing this shinyApp. It's main aim is to investigate on the variables of a dataset. First it produces the summary statistics on the selected variable.
In the second part; I want this app to give me the pairplot of the varibles that I have selected in the checkbox in the UI. I have used the dataset IRIS which is available to everyone, but I need the code to be adaptable to other datasets.
Can someone please help me?
library(shiny)
library(plotly)
data(iris)
ui<-fluidPage(
titlePanel("Iris"),
sidebarLayout(
sidebarPanel(
selectInput("var",label="Choose a variable",
choice=list("Sepal.Length"=1, "Sepal.Width"=2, "Petal.Length"=3, "Petal.Width"=4, "Species"=5), selectize=FALSE),
checkboxGroupInput(inputId ="independent",label = "Select independent variables", choices = names(iris)),
mainPanel(
verbatimTextOutput("sum"),
plotlyOutput('plot_id_in_ui ', height = "900px")
)
))
)
server<-function(input,output){
output$sum <- renderPrint({
summary(iris[, as.numeric(input$var)])
})
output$plot_id_in_ui <- renderplot( { "DON'T KNOW HOW TO WRITE THIS PART"
pairplot(iris, varnames, type = "both", penalty.par.val = "lambda.1se",
nvals = c(20, 20), pred.type = "response") } )
})
shinyApp(ui, server)
Maybe this little example can help you. It illustrates how to plot a normal R-Plot and a Plotly-Plot in a ShinyApp:
library(shiny)
library(plotly)
ui <- fluidPage(
titlePanel("Iris"),
sidebarLayout(
sidebarPanel(
selectInput("var",label="Choose a variable",
choice=list("Sepal.Length"=1, "Sepal.Width"=2, "Petal.Length"=3, "Petal.Width"=4, "Species"=5), selectize=FALSE),
checkboxGroupInput(inputId ="independent",label = "Select independent variables", choices = names(iris))
),
mainPanel(
verbatimTextOutput("sum"),
plotOutput("plot"),
plotlyOutput("plotly")
)
)
)
server <- function(input,output) {
output$sum <- renderPrint({
summary(iris[, as.numeric(input$var)])
})
output$plot <- renderPlot({
plot(iris)
})
output$plotly <- renderPlotly({
plot_ly(iris) %>%
add_trace(x=iris$Sepal.Length, y=iris$Sepal.Width, type="scatter", mode="markers")
})
}
shinyApp(ui, server)

selectInput based on columns of uploading csv file

I am trying to build a shiny app where I can upload a csv file and based on the column names, from selectInput - app shows basic statistic (graphs, descriptive statistic-average, sd, var .... and some statistical tests).
There is no problem with datasets, which are already in the app. Also no problem with statistics.
Problem is how to make working selectInput with the names of columns from new upload csv file.
Here is my light version of code:
UI:
library(shiny)
shinyUI(fluidPage(
titlePanel("xxx"),
sidebarLayout(
sidebarPanel(
fileInput("csvFile", "Drag cars.csv over here!"),
selectInput("var", "choose variable:", choices= names(data()))
),
mainPanel(
textOutput("average"),
plotOutput("plot")
)
)
))
SERVER:
shinyServer(function(input, output, session) {
data <- reactive({
file1 <- input$csvFile
if (is.null(file1)) {
return()
}
data = read.csv(file=file1$datapath)
data
})
output$average <- renderText({
paste("average is: ", mean(data()[,input$var]))
})
output$plot <- renderPlot({
boxplot(data()[,input$var])
})
})
You will need to use uiOutput() and renderUI() functions.
library(shiny)
ui <- fluidPage(
titlePanel("xxx"),
sidebarLayout(
sidebarPanel(
fileInput("csvFile", "Drag cars.csv over here!"),
uiOutput("var_ui")
),
mainPanel(
textOutput("average"),
plotOutput("plot")
)
)
)
server <- function(input, output, session) {
data <- reactive({
file1 <- input$csvFile
if (is.null(file1)) {
return()
}
data = read.csv(file=file1$datapath)
data
})
output$average <- renderText({
paste("average is: ", mean(data()[,input$var]))
})
output$plot <- renderPlot({
boxplot(data()[,input$var])
})
output$var_ui <- renderUI({
selectInput("var", "choose variable:", choices= names(data()))
})
}
shinyApp(ui, server)
You can also use observe in server. observe does not return anything. Unlike reactive, it responds immediately (and not lazily). It's best used for ip/op operations.
observe({
updateSelectInput(
session,
"var",
choices = names(data())
)
)}

Resources