so I want to make a data table in Shiny that displays only the number of rows that the user inputs. The only other input is which dataset the user wants to see (iris, diamond, or storms). But I can not figure out how to make the table so that it will let you switch between datasets and change the number of rows displayed, I can only do one or the other. I would really appreciate some help. I am really new to R so i'm sorry if this is a simple question. I've looked at similar questions and still can't figure it out. Thank you.(I also have a summary that is printed too but that works fine its just the table that is a problem).
ui <- fluidPage(
selectInput("dataset", "Choose Dataset", choices = c("iris", "storms", "diamonds")), # 3 dataset options for user to pick from
numericInput("num", "Row Number To Display", value = 0, min = 0, max = 100), # row number selection
verbatimTextOutput("summary"),
dataTableOutput("table")
)
server <- function(input, output, session) {
output$summary <- renderPrint({
dataset <- get(input$dataset)
summary(dataset)
})
output$table <- renderDataTable({
dataset <- get(input$dataset)
options = list(pageLength = input$num)
dataset
})
}
shinyApp(ui, server)
Subset the table to be displayed by input$num.
output$table <- renderDataTable({
dataset <- get(input$dataset)
dataset[seq_len(input$num), ]
})
Complete Code -
library(shiny)
ui <- fluidPage(
selectInput("dataset", "Choose Dataset", choices = c("iris", "storms", "diamonds")), # 3 dataset options for user to pick from
numericInput("num", "Row Number To Display", value = 0, min = 0, max = 100), # row number selection
verbatimTextOutput("summary"),
dataTableOutput("table")
)
server <- function(input, output, session) {
output$summary <- renderPrint({
dataset <- get(input$dataset)
summary(dataset)
})
output$table <- renderDataTable({
dataset <- get(input$dataset)
dataset[seq_len(input$num), ]
})
}
shinyApp(ui, server)
This is a sample application where in the table is displayed as per values selected from dropdown(more than 2 values).
Right now the user can select only from dropdown. But can we add additional feature where (say from excel there are values column wise
Now the user can copy this values and paste it on selectinput. Then these values should be taken in the selectinput.
Basically the user should be able to copy and paste values into selectinput widget
library(shiny)
library(DT)
dat <- mtcars
server <- function(input, output, session) {
output$ui_view_vars <- renderUI({
vars <- colnames(dat)
## using selectizeInput with drag_drop and DT
selectizeInput("view_vars", "Select variables to show:", choices = vars,
selected = "", multiple = TRUE,
options = list(plugins = list('drag_drop')))
})
output$dataviewer <- DT::renderDataTable({
if (is.null(input$view_vars)) return()
DT::datatable(dat[,input$view_vars])
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
uiOutput("ui_view_vars")
),
mainPanel(
tabPanel("View", DT::dataTableOutput("dataviewer"))
)
)
)
shinyApp(ui = ui, server = server)
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)
My ui.R function is as shown below.
library(shiny)
shinyUI(pageWithSidebar(
headerPanel("Add Features"),
sidebarPanel(width=4,
fluidRow(
column(6, selectInput("features", label = h3("Features"),
choices = list("Feature1","Feature2","Feature3"), selected = "Feature1")),
br(),
br(),
column(6, numericInput("n", label="",min = 0, max = 100, value = 50)),
br(),
column(2, actionButton("goButton", "Add!"))
#column(3, submitButton(text="Analyze"))
)),
mainPanel(
verbatimTextOutput("nText"),
textOutput("text2")
)
))
My server.R function is as below:
library(shiny)
shinyServer(function(input, output) {
selFeatures <- data.frame()
valFeatures <- data.frame()
# builds a reactive expression that only invalidates
# when the value of input$goButton becomes out of date
# (i.e., when the button is pressed)
ntext <- eventReactive(input$goButton, {
selFeatures <- rbind(selFeatures,input$features)
valFeatures <- rbind(valFeatures,input$n)
paste("The variables are",input$features,input$n)
paste("The variables are",selFeatures,valFeatures)
})
output$nText <- renderText({
ntext()
})
output$text2 <- renderText({
paste("You have selected", input$features)
})
})
What I want to do is ask user to input some variables. Here Feature1, Feature2, and Feature3. User has to input Feature1 but Feature2 and Feature3 are optional. So, here user selects a feature, inputs its value in numericInput and presses button Add. When Add is pressed after selecting Feature1, user can select to submit the form or add features 2 and 3 using the add button. I finally, want to use these three variables to learn a prediction model. How can I collect all the imputed information in the dataframe to process it. Also, if possible to remove Feature1 from the selectBox after it has been added. I want my UI to look like the following before Pressing the add button
and it should look like the following after pressing the add button.
The feature1 here need not be in the select box, just a way to display that it has been added is fine.
I wasn't quite sure why you wanted to use selectInputs for setting the variable values so here's a general example on how to access inputs from dynamically generated content:
library(shiny)
ui <- shinyUI(pageWithSidebar(
headerPanel("Add Features"),
sidebarPanel(width=4,
fluidRow(column(12,
h3('Features'),
uiOutput('uiOutpt')
)), # END fluidRow
fluidRow(
column(4,div()),
column(4,actionButton("add", "Add!")),
column(4,actionButton('goButton',"Analyze"))
) # END fluidRow
), # END sidebarPanel
mainPanel(
verbatimTextOutput("nText"),
textOutput("text2"),
tableOutput('tbl')
)
))
server <- shinyServer(function(input, output) {
features <- reactiveValues(renderd=c(1))
ntext <- eventReactive(input$goButton, {
out <- lapply(features$renderd,function(i){
fv <- paste0('numInp_',i)
vn <- paste0('Feature',i)
# Get input values by namw
sprintf( 'Variable: %s, Value: %5.3f',input[[vn]],input[[fv]] )
})
do.call(paste,c(out,sep="\n"))
})
df <- eventReactive(input$goButton, {
out <- lapply(features$renderd,function(i){
fv <- paste0('numInp_',i)
vn <- paste0('Feature',i)
data.frame(Variable=input[[vn]], Value=input[[fv]] )
})
do.call(rbind,out)
})
output$nText <- renderText({
ntext()
})
output$text2 <- renderText({
sprintf("You have selected feature: %s", paste(features$renderd,collapse=", "))
})
output$tbl <- renderTable({
df()
})
# Increment reactive values used to store how may rows we have rendered
observeEvent(input$add,{
if (max(features$renderd) > 2) return(NULL)
features$renderd <- c(features$renderd, max(features$renderd)+1)
})
# If reactive vector updated we render the UI again
observe({
output$uiOutpt <- renderUI({
# Create rows
rows <- lapply(features$renderd,function(i){
fluidRow(
column(6, selectInput(paste0('Feature',i),
label = "",
choices = list("Feature1","Feature2","Feature3"),
selected = paste0('Feature',i))),
column(6, numericInput(paste0('numInp_',i), label="",min = 0, max = 100, value = runif(1,max=100)))
)
})
do.call(shiny::tagList,rows)
})
})
})
shinyApp(ui=ui,server=server)
I'm simply storing the ID's of the dynamically generated content in a vector that helps me keep track of what I've generated. To access the values i simply reconstruct the elements ID from the numbers stored in the vector.
Oskar's answer was very useful to me for a similar challenge I faced; for unlimited features, I figured out how to enable a "remove" button and to keep values when pressing the "add" button. For posterity, here are my modifications to Oskar's code:
library(shiny)
ui <- shinyUI(pageWithSidebar(
headerPanel("Add Features"),
sidebarPanel(width=4,
fluidRow(column(12,
h3('Features'),
uiOutput('uiOutpt')
)), # END fluidRow
fluidRow(
column(4,div()),
column(4,actionButton("add", "Add!")),
column(4,actionButton("remove", "Remove!")),
column(4,actionButton('goButton',"Analyze"))
) # END fluidRow
), # END sidebarPanel
mainPanel(
textOutput("text2"),
tableOutput('tbl')
)
))
server <- shinyServer(function(input, output) {
features <- reactiveValues(renderd=c(1),
conv=c(50),
inlabels=c('A'),
outlabels=c('B'))
df <- eventReactive(input$goButton, {
out <- lapply(features$renderd,function(i){
fv <- paste0('numInp_',i)
vn <- paste0('InLabel',i)
data.frame(Variable=input[[vn]], Value=input[[fv]] )
})
do.call(rbind,out)
})
output$nText <- renderText({
ntext()
})
output$text2 <- renderText({
paste(sprintf("You have selected feature: %s", paste(features$renderd,collapse=", ")))
})
output$tbl <- renderTable({
df()
})
# Increment reactive values array used to store how may rows we have rendered
observeEvent(input$add,{
out <- lapply(features$renderd,function(i){
fv <- paste0('numInp_',i)
vn <- paste0('InLabel',i)
vo <- paste0('OutLabel',i)
data.frame(inlabels=input[[vn]],outlabels=input[[vo]], conv=input[[fv]] )
})
df<-do.call(rbind,out)
print(df)
features$inlabels <- c(as.character(df$inlabels),' ')
features$outlabels <- c(as.character(df$outlabels),' ')
print(c(features$inlabels,features$outlabels))
features$renderd <- c(features$renderd, length(features$renderd)+1)
print(features$renderd)
print(names(features))
features$conv<-c(df$conv,51-length(features$renderd))
})
observeEvent(input$remove,{
features$renderd <- features$renderd[-length(features$renderd)]
})
# If reactive vector updated we render the UI again
observe({
output$uiOutpt <- renderUI({
# Create rows
rows <- lapply(features$renderd,function(i){
fluidRow(
# duplicate choices make selectize poop the bed, use unique():
column(4, selectizeInput(paste0('InLabel',i),
label = 'Input Name',selected=features$inlabels[i],
choices=unique(c(features$inlabels[i],features$outlabels[!features$outlabels %in% features$inlabels])),
options = list(create = TRUE))),
column(4, sliderInput(paste0('numInp_',i), label="Conversion",min = 0, max = 100, value = features$conv[i])),
column(4, selectizeInput(paste0('OutLabel',i),
label = "Output Name", selected=features$outlabels[i],
choices=unique(c(features$inlabels,features$outlabels)),
options = list(create = TRUE)))
)
})
do.call(shiny::tagList,rows)
})
})
})
shinyApp(ui=ui,server=server)