I am using R shiny to develop a interactive analysis tool. Now I want to do classification tree based on variables check in checkboxGroupInput. How can I select that subset of data? THX!
UI:
dateInput("date","Enter date:",value = date),
checkboxGroupInput("variable", "Variable:",
choices = names ,selected = names
)
server I tried, but doesn't work:
dataall <- reactive({
filename <- paste0("dataall_'", input$date, "'.RData")
load(filename)
feature.test[,names(feature.test) %in% input$variable]
})
feature.test is data in loaded file.
Hard to understand what you want since you don't subset the file you load. What is feature.test ?
Here is a simple example to how to subset a data frame using an input and shiny reactivity :
shiny::runApp(list(
ui = basicPage(
selectInput("specy", "Specy", choices = levels(iris$Species)),
tableOutput("content")
),
server = function(input, output, session) {
output$content <- renderTable({
iris[iris$Species == input$specy, ]
})
}
))
EDIT ## :
Subset by column :
shiny::runApp(list(
ui = pageWithSidebar(
headerPanel("Example"),
sidebarPanel(
checkboxGroupInput("variable", "Variable:", choices = names(iris))
),
mainPanel(
tableOutput("content")
)
),
server = function(input, output, session) {
output$content <- renderTable({
if(is.null(input$variable))
return()
iris[input$variable]
})
}
))
"variable" is supposed to be "date" since this is the control that you are referencing in the UI part, as in:
checkboxGroupInput( "date", "Variable:",
choices = names ,selected = names
)
For data.table you need to add a ,with=FALSE or use a temporary variable in the server code:
# Load libraries
library(shiny)
library(data.table)
# Copy dataset
irisDT=copy(iris)
setDT(irisDT)
# Shiny app
shiny::runApp(list(
# UI
ui = pageWithSidebar(
headerPanel("Example"),
sidebarPanel(
checkboxGroupInput("variable", "Variable:", choices = names(iris))
),
mainPanel(
tableOutput("content")
)
),
# Server
server = function(input, output, session) {
output$content <- renderTable({
if(is.null(input$variable))
return()
# iris[input$variable] # data.frame
irisDT[, input$variable, with=FALSE] # data.table
# Alternatively:
# tmp <- input$variable
# irisDT[, ..tmp]
})
}
))
Related
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 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())
)
)}
I am trying to create a sidebar that outputs the columns of a datatable and the number of unique values in each column. The code below works for the names but when it comes to the unique values I can only get it to display if the list variable is unlist()ed. I could not find any articles that talk about getting a textOutput or equivalent that would handle a list variable across multiple rows.
library(shiny)
data(mtcars)
if (interactive()) {
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(
column(6, checkboxGroupInput("dsnamesGrp","Variable name")),
column(6, uiOutput("dsordsGrp"), inline= FALSE)
)
),
mainPanel(
dataTableOutput('contents'))
)
)
server <- function(input, output, session) {
output$contents <- renderDataTable({mtcars})
dsnames <- list()
dsnames <- names(mtcars)
cb_options <- list()
cb_options[dsnames] <- dsnames
updateCheckboxGroupInput(session, "dsnamesGrp",
label = "Column name",
choices = cb_options,
selected = "")
ord_values <- list()
ord_values <- lapply(mtcars, function(x)length(unique(x)))
output$dsordsGrp <- renderText({unlist(ord_values)})
}
}
shinyApp(ui, server)
We can use the lengths on the unique elements on the list
ord_values <- lengths(lapply(mtcars, unique))
output$dsordsGrp <- renderText({ord_values})
-full code
library(shiny)
data(mtcars)
if (interactive()) {
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(
column(6, checkboxGroupInput("dsnamesGrp","Variable name")),
column(6, htmlOutput("dsordsGrp"), inline= FALSE)
)
),
mainPanel(
dataTableOutput('contents'))
)
)
server <- function(input, output, session) {
output$contents <- renderDataTable({mtcars})
dsnames <- names(mtcars)
cb_options <- list()
cb_options[dsnames] <- dsnames
updateCheckboxGroupInput(session, "dsnamesGrp",
label = "Column name",
choices = cb_options,
selected = "")
output$dsordsGrp <- renderUI({
HTML(paste(lengths(lapply(mtcars, unique)), collapse="<br/>"))
})
}
}
shinyApp(ui, server)
Or if we are using the same code as in the OP, instead of lapply (always returns a list output) use sapply which returns a vector because the default argument is simplify = TRUE and with that it uses the simplify2array
ord_values <- sapply(mtcars, function(x)length(unique(x)))
output$dsordsGrp <- renderText({ord_values})
EDIT: changed renderText to renderUI
I want to print data set values in R shiny web app. But below code is printing the name of dataset in UI output. How can I print values of dataset?
library(MASS)
library(shinythemes)
library(shiny)
library(ggplot2)
mass.tmp <- data(package = "MASS")[3]
mass.datasets <- as.vector(mass.tmp$results[,3])
ui <- fluidPage(
theme = shinytheme("superhero"),
titlePanel("Linear Regression Modelling"),
sidebarLayout(
sidebarPanel(
selectInput("dsname", "Dataset:",choices = c(mass.datasets))
,
uiOutput("x_axis")
,
tableOutput("tab")
),
mainPanel(
tags$br(),
tags$br()
)
)
)
server <- function(input, output) {
num_ds <- function(ds)
{
nums <- sapply(ds,is.numeric)
num_ds <- ds[,nums]
return(num_ds)
}
ds_ext <- reactive({ num_ds(input$dsname) })
output$tab <- renderTable({ eval(input$dsname) })
# output$x_axis <- renderUI({
# col_opts <- get(ds_ext())
# selectInput("x_axis2", "Independent Variable:", choices = names(col_opts))
# })
}
shinyApp(ui = ui, server = server)
This is full code. I am trying to display data set from MASS package as you see in the code above.
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)