I'd like to create a dynamic and hierarchical sidebarLayout using the selectInput
variables information. I have a pet information data frame (myds) and for example, I choose dog option in "selectedvariable1" pet, then in "selectedvariable3" the options need to be "collie" or "pit-bull", not "birman" or "bobtail" because the option in "selectedvariable1"is a dog, not a cat.
In my example:
# Packages
library(shiny)
# Create my data set
pet<-c("dog","dog","cat","cat")
fur<-c("long","short","long","short")
race<-c("collie","pit-bull","birman","bobtail")
sweetness<-c("high","medium","high","medium")
myds<-data.frame(pet,fur,race,sweetness)
# Create the pet shiny dash
ui <- fluidPage(
titlePanel(title="My Pet Dashboard"),
sidebarLayout(
sidebarPanel(
uiOutput("selectedvariable1"),
uiOutput("selectedvariable2"),
uiOutput("selectedvariable3"),
uiOutput("selectedvariable4")
),
mainPanel(
textOutput("idSaida")
)
)
)
server <- function(input, output,session){
currentvariable1 <- reactive({input$selectedvariable1})
currentvariable2 <- reactive({input$selectedvariable2})
currentvariable3 <- reactive({input$selectedvariable3})
currentvariable4 <- reactive({input$selectedvariable4})
output$selectedvariable1 <- renderUI({
selectInput("selectedvariable1",
label = "Pet type",
choices = unique(myds$pet),
selected = TRUE )
})
data2 <- reactive({
data2 <- subset(myds, fur %in% unique(currentvariable2()))
})
output$selectedvariable2 <- renderUI({
data2 <- subset(myds, pet %in% unique(currentvariable1()))
selectInput("selectedvariable2",
label = "Fur style",
choices = unique(data2$fur),
selected = TRUE )
})
data3 <- reactive({
data3 <- subset(data2, fur %in% unique(currentvariable2()))
})
output$selectedvariable3 <- renderUI({
selectInput("selectedvariable3",
label = "Race name",
choices = unique(data3$race),
selected = TRUE )
})
data4 <- reactive({
data4 <- subset(data2, fur %in% unique(currentvariable3()))
})
output$selectedvariable4 <- renderUI({
selectInput("selectedvariable4",
label = "Sweetness behaviour",
choices = unique(data4$sweetness),
selected = TRUE )
})
}
shinyApp(ui, server)
##
Please, anyone can help me with this question?
Try this
server <- function(input, output,session){
# currentvariable1 <- reactive({input$selectedvariable1})
# currentvariable2 <- reactive({input$selectedvariable2})
# currentvariable3 <- reactive({input$selectedvariable3})
# currentvariable4 <- reactive({input$selectedvariable4})
output$selectedvariable1 <- renderUI({
selectInput("selectedvariable1",
label = "Pet type",
choices = unique(myds$pet),
selected = TRUE )
})
data2 <- reactive({
req(input$selectedvariable1)
data2 <- subset(myds, pet %in% input$selectedvariable1)
})
output$selectedvariable2 <- renderUI({
req(data2())
#data2 <- subset(data2(), pet %in% unique(currentvariable1()))
selectInput("selectedvariable2",
label = "Fur style",
choices = unique(data2()$fur),
selected = TRUE )
})
data3 <- reactive({
req(input$selectedvariable2,data2())
data3 <- subset(data2(), fur %in% input$selectedvariable2)
})
output$selectedvariable3 <- renderUI({
req(data2())
selectInput("selectedvariable3",
label = "Race name",
choices = unique(data2()$race), ## use data3() instead of data2(), if you wish to subset from data3()
selected = TRUE )
})
data4 <- reactive({
req(input$selectedvariable3,data2())
data4 <- subset(data2(), race %in% input$selectedvariable3)
})
output$selectedvariable4 <- renderUI({
req(data4())
selectInput("selectedvariable4",
label = "Sweetness behaviour",
choices = data4()$sweetness,
selected = TRUE )
})
}
shinyApp(ui, server)
Something like this should work, add this to server function and adapt to your code:
observeEvent(input$selectedvariable1,{
if (input$selectedvariable1=="dog") {
updateSelectInput("selectedvariable3", choices=c("collie","pit-bull"))
}
})
Related
I'm trying to figure out how to navigate through lists in R (I've mostly worked with vectors to-date in R). The Shiny code posted at the bottom allows the user to dynamically add/delete tables, and I'm trying to capture in a separate list or vector the column names of the added tables. (I'm trying to capture the column names so I can populate a pending selectizeInput() function for choosing which tables to delete). Any recommendations for how to do this?
As you can see in my print() function in the code below, I am only extracting a high-level name, but instead would like to drill deeper to the column names of the individual tables. The following illustrations explain better.
In this illustration the user has added 2 tables, in addition to the first default table:
And in this illustration, the print() function produces the following list names in R Studio Console when I would like to instead only show "Col 1", "Col 2", and "Col 3", in this example of 2 clicks of "Add table":
Code:
library(shiny)
library(rhandsontable)
data1 <- data.frame(row.names = c("A","B","C","Sum"),"Col 1"=c(1,1,0,2),check.names=FALSE)
ui <- fluidPage(
br(),
actionButton("addTbl","Add table"),
br(),br(),
tags$div(id = "placeholder",
tags$div(
style = "display: inline-block",
rHandsontableOutput("hottable1")
)
)
)
server <- function(input, output, session) {
uiTbl <- reactiveValues(div_01_tbl = data1)
rv <- reactiveValues()
observeEvent(input$hottable1, {uiTbl$div_01_tbl <- hot_to_r(input$hottable1)})
observe({
divID <- paste0("div_", sprintf("%02d", input$addTbl+1))
dtID <- paste0(divID, "_DT")
btnID <- paste0(divID, "_rmv")
uiTbl[[paste0(divID,"_tbl")]] <- data1 # captures initial dataframe values
insertUI(
selector = "#placeholder",
ui = tags$div(
id = divID,
style = "display:inline-block;",
rHandsontableOutput(dtID),
actionButton(btnID, "Delete", class = "pull-left btn btn-danger"),
)
)
output[[dtID]] <- renderRHandsontable({
req(uiTbl[[paste0(divID,"_tbl")]])
rhandsontable(uiTbl[[paste0(divID,"_tbl")]], useTypes = TRUE)
})
observeEvent(input[[dtID]], {uiTbl[[paste0(divID,"_tbl")]] <- hot_to_r(input[[dtID]])})
observeEvent(input[[btnID]],{
removeUI(selector = paste0("#", divID))
rv[[divID]] <- NULL
uiTbl[[paste0(divID,"_tbl")]] <- NULL
},
ignoreInit = TRUE,
once = TRUE
)
})
observe({
tables_list <- reactiveValuesToList(uiTbl)
tables_list <- tables_list[order(names(tables_list))]
table_lengths <- lengths(tables_list)
cumsum_table_lengths <- cumsum(table_lengths)[table_lengths != 0L]
for(i in seq_along(cumsum_table_lengths)){
names(uiTbl[[names(cumsum_table_lengths[i])]]) <- paste("Col", cumsum_table_lengths[i])
}
print(names(uiTbl))
})
}
shinyApp(ui, server)
observe({
print(paste0(lapply(
Filter(
\(x)!is.null(x),
reactiveValuesToList(uiTbl)
),
names
), collapse = "; "))
})
Here is one albeit long-winded solution, resorting to my familiarity with data frames. I am sure there are cleaner approaches. See the inclusion of "tmp" objects in the last observe() for the core of my solution; I send the reactive values list into a dataframe and manipulate from there. I also include the selectizeInput() using renderUI() also embedded in the last observe() so you can see the point of my question. Rather than sending the desired vector to R Studio console via print() as in the OP, I send it to global environment as "tmp.R" so I can review more intricate input sequences.
library(dplyr)
library(rhandsontable)
library(shiny)
data1 <- data.frame(row.names = c("A","B","C","Sum"),"Col 1"=c(1,1,0,2),check.names=FALSE)
ui <- fluidPage(
br(),
actionButton("addTbl","Add table"),
br(),br(),
uiOutput("delSection"),
tags$div(id = "placeholder",
tags$div(
style = "display: inline-block",
rHandsontableOutput("hottable1")
)
)
)
server <- function(input, output, session) {
uiTbl <- reactiveValues(div_01_tbl = data1)
rv <- reactiveValues()
observeEvent(input$hottable1, {uiTbl$div_01_tbl <- hot_to_r(input$hottable1)})
observe({
divID <- paste0("div_", sprintf("%02d", input$addTbl+1))
dtID <- paste0(divID, "_DT")
btnID <- paste0(divID, "_rmv")
uiTbl[[paste0(divID,"_tbl")]] <- data1 # captures initial dataframe values
insertUI(
selector = "#placeholder",
ui = tags$div(
id = divID,
style = "display:inline-block;",
rHandsontableOutput(dtID),
actionButton(btnID, "Delete", class = "pull-left btn btn-danger"),
)
)
output[[dtID]] <- renderRHandsontable({
req(uiTbl[[paste0(divID,"_tbl")]])
rhandsontable(uiTbl[[paste0(divID,"_tbl")]], useTypes = TRUE)
})
observeEvent(input[[dtID]], {uiTbl[[paste0(divID,"_tbl")]] <- hot_to_r(input[[dtID]])})
observeEvent(input[[btnID]],{
removeUI(selector = paste0("#", divID))
rv[[divID]] <- NULL
uiTbl[[paste0(divID,"_tbl")]] <- NULL
},
ignoreInit = TRUE,
once = TRUE
)
})
observe({
tables_list <- reactiveValuesToList(uiTbl)
tables_list <- tables_list[order(names(tables_list))]
table_lengths <- lengths(tables_list)
cumsum_table_lengths <- cumsum(table_lengths)[table_lengths != 0L]
for(i in seq_along(cumsum_table_lengths)){
names(uiTbl[[names(cumsum_table_lengths[i])]]) <- paste("Col", cumsum_table_lengths[i])
}
tmp <- data.frame(cumsum_table_lengths)
tmp <- data.frame(origTbl = rownames(tmp), tblCnt = tmp[,1])
tmp <- tmp %>% mutate(tblCode = paste("Col",tblCnt))
tmp.R <<- tmp
output$delSection <-
renderUI(
tagList(
selectizeInput(
'delSelector',
'Select table for deletion:',
choices = tmp[,3],
multiple = FALSE,
options = list(placeholder = 'Choose table')
),
p(actionButton('delTbl', 'Delete'))
)
)
})
}
shinyApp(ui, server)
Here I'm using 'mtcars' and will like to update my selectInputs based on the unique values in some column. First, we choose the type of engine and subset the data. Then we choose the cylinder but based on the remaining cylinder options in the subsetted data, and so forth. Last, we print the names of the cars. Code, which is not working, is as below:
library(shiny)
df <- mtcars
ui <- fluidPage(
sidebarPanel(
selectInput("engine", "Select engine:", choices = unique(df$vs)),
selectInput("cylinder", "Select cylinder:", choices = ""),
selectInput("gear", "Select gear:", choices = ""),
),
mainPanel(
textOutput("results")
)
)
server <- function(input, output, session) {
data <- reactiveValues()
observeEvent(input$engine, {
tmp <- df
tmp1 <- tmp[tmp$vs == as.numeric(input$engine),]
updateSelectInput(session, "cylinder", choices = unique(tmp1$cyl))
data()$tmp1 <- tmp1
})
observeEvent(input$cylinder,{
tmp1 <- data()$tmp1
tmp2 <- tmp1[tmp1$cyl == as.numeric(input$cylinder),]
updateSelectInput(session, "gear", choices = unique(tmp2$gear))
data()$tmp2 <- tmp2
})
observeEvent(input$gear,{
tmp2 <- data()$tmp2
tmp3 <- tmp2[tmp2$gear == as.numeric(input$gear),]
data()$tmp3 <- tmp3
})
output$results <- renderText({
print(row.names(data()$tmp3))
})
}
shinyApp(ui = ui, server = server)
The issue is that you try to access your reactiveValues data using data(). Instead, to set or get a value use e.g. data$tmp1 without parentheses. See ?reactiveValues.
library(shiny)
df <- mtcars
ui <- fluidPage(
sidebarPanel(
selectInput("engine", "Select engine:", choices = unique(df$vs)),
selectInput("cylinder", "Select cylinder:", choices = ""),
selectInput("gear", "Select gear:", choices = ""),
),
mainPanel(
textOutput("results")
)
)
server <- function(input, output, session) {
data <- reactiveValues()
observeEvent(input$engine, {
tmp <- df
tmp1 <- tmp[tmp$vs == input$engine, ]
updateSelectInput(session, "cylinder", choices = unique(tmp1$cyl))
data$tmp1 <- tmp1
})
observeEvent(input$cylinder, {
tmp1 <- data$tmp1
tmp2 <- tmp1[tmp1$cyl == input$cylinder, ]
updateSelectInput(session, "gear", choices = unique(tmp2$gear))
data$tmp2 <- tmp2
})
observeEvent(input$gear, {
tmp2 <- data$tmp2
tmp3 <- tmp2[tmp2$gear == input$gear, ]
data$tmp3 <- tmp3
})
output$results <- renderText({
print(row.names(data$tmp3))
})
}
shinyApp(ui = ui, server = server)
#>
#> Listening on http://127.0.0.1:5721
#> character(0)
#> [1] "Mazda RX4" "Mazda RX4 Wag"
I have a fully functioning shiny app for performing regression analysis, with summary(), tidy(), and augment().
However, I would like to add a filter selection in the shiny for the uploaded data.
My dataset is quite big and within the dataset, it is divided into 5 types, (so, type_1, type_2, type_3, etc). Right now I have to divide my dataset manually outside the shiny app to 5 different datasets so I can only run the regression for one specific type at a time.
It would be great to be able to choose and select the type within the shiny, without going through all this hassle.
Grateful for all your help.
library(shiny)
library(shinyWidgets)
library(DT)
library(dplyr)
library(nlme)
library(broom)
ui <- navbarPage("dd",
tabPanel("Reg",
sidebarPanel(
fileInput(
inputId = "filedata",
label = "Upload data. csv",
multiple = FALSE,
accept = c(".csv"),
buttonLabel = "Choosing ...",
placeholder = "No files selected yet"
),
uiOutput("xvariable"),
uiOutput("yvariable")
),
mainPanel(
DTOutput("tb1"),
fluidRow(
column(6, verbatimTextOutput('lmSummary')),
column(6,verbatimTextOutput("tid")),
column(6,verbatimTextOutput("aug"))
)
)
)
)
server <- function(input, output, session) {
data_1 <- reactive({
req(input$filedata)
inData <- input$filedata
if (is.null(inData)){ return(NULL) }
mydata <- read.csv(inData$datapath, header = TRUE, sep=",")
})
output$tb1 <- renderDT(head(data_1()))
output$xvariable <- renderUI({
req(data_1())
xa<-colnames(data_1())
pickerInput(inputId = 'xvar',
label = 'Select x-axis variable',
choices = c(xa[1:length(xa)]), selected=xa[2],
options = list(`style` = "btn-info"),
multiple = TRUE)
})
output$yvariable <- renderUI({
req(data_1())
ya<-colnames(data_1())
pickerInput(inputId = 'yvar',
label = 'Select y-axis variable',
choices = c(ya[1:length(ya)]), selected=ya[1],
options = list(`style` = "btn-info"),
multiple = FALSE)
})
lmModel <- reactive({
req(data_1(),input$xvar,input$yvar)
x <- as.numeric(data_1()[[as.name(input$xvar)]])
y <- as.numeric(data_1()[[as.name(input$yvar)]])
current_formula <- paste0(input$yvar, " ~ ", paste0(input$xvar, collapse = " + "))
current_formula <- as.formula(current_formula)
model <- lm(current_formula, data = data_1(), na.action=na.exclude)
return(model)
})
output$lmSummary <- renderPrint({
req(lmModel())
summary(lmModel())
})
output$tid <- renderPrint({
req(lmModel())
tidy(lmModel())
})
output$aug <- renderPrint({
req(lmModel())
augment(lmModel())
})
}
shinyApp(ui, server)
How the uploaded dataset could look like, for better explanation
data_set <- data.frame (Simulation_1 = c(1,2,3,4,5,6,7,8,9,10),
Simulation_2 = c(1,2,3,4,5,6,7,8,9,10),
Simulation_3 = c(1,2,3,4,5,6,7,8,9,10),
type = c("type_1", "type_2", "Type_5",
"type_1", "type_2", "Type_3",
"type_1", "type_2", "Type_1","Type_4")
)
Perhaps you are looking for this
library(shiny)
library(shinyWidgets)
library(DT)
library(dplyr)
library(nlme)
library(broom)
data_set <- data.frame (Simulation_1 = c(1,2,3,4,5,6,7,8,9,10),
Simulation_2 = c(1,2,3,4,5,6,7,8,9,10),
Simulation_3 = c(1,2,3,4,5,6,7,8,9,10),
type = c("type_1", "type_2", "Type_5",
"type_1", "type_2", "Type_3",
"type_1", "type_2", "Type_1","Type_4")
)
ui <- navbarPage("dd",
tabPanel("Reg",
sidebarPanel(
fileInput(
inputId = "filedata",
label = "Upload data. csv",
multiple = FALSE,
accept = c(".csv"),
buttonLabel = "Choosing ...",
placeholder = "No files selected yet"
),
uiOutput("col"),
uiOutput("type"),
uiOutput("xvariable"),
uiOutput("yvariable")
),
mainPanel(
DTOutput("tb1"),
fluidRow(
column(6, verbatimTextOutput('lmSummary')),
column(6,verbatimTextOutput("tid")),
column(6,verbatimTextOutput("aug"))
)
)
)
)
server <- function(input, output, session) {
data_0 <- reactive({
# req(input$filedata)
# inData <- input$filedata
# if (is.null(inData)){ return(NULL) }
# mydata <- read.csv(inData$datapath, header = TRUE, sep=",")
data_set
})
output$tb1 <- renderDT(head(data_1()))
output$col <- renderUI({
req(data_0())
selected = colnames(data_0())[length(colnames(data_0()))]
selectInput("mycol", "Choose column", choices = colnames(data_0()), selected = selected)
})
output$type <- renderUI({
req(data_0(),input$mycol)
selectInput("mytype", "Choose Type", choices = unique(data_0()[[input$mycol]]))
})
data_1 <- eventReactive(input$mytype, {
req(data_0(),input$mycol,input$mytype)
df <- data_0()
df$newvar <- df[[input$mycol]]
df %>% dplyr::filter(newvar %in% input$mytype) %>% dplyr::select(- c(newvar))
})
output$xvariable <- renderUI({
req(data_1())
xa<-colnames(data_1())
pickerInput(inputId = 'xvar',
label = 'Select x-axis variable',
choices = c(xa[1:length(xa)]), selected=xa[2],
options = list(`style` = "btn-info"),
multiple = TRUE)
})
output$yvariable <- renderUI({
req(data_1())
ya<-colnames(data_1())
pickerInput(inputId = 'yvar',
label = 'Select y-axis variable',
choices = c(ya[1:length(ya)]), selected=ya[1],
options = list(`style` = "btn-info"),
multiple = FALSE)
})
lmModel <- reactive({
req(data_1(),input$xvar,input$yvar)
x <- as.numeric(data_1()[[as.name(input$xvar)]])
y <- as.numeric(data_1()[[as.name(input$yvar)]])
current_formula <- paste0(input$yvar, " ~ ", paste0(input$xvar, collapse = " + "))
current_formula <- as.formula(current_formula)
model <- lm(current_formula, data = data_1(), na.action=na.exclude)
return(model)
})
output$lmSummary <- renderPrint({
req(lmModel())
summary(lmModel())
})
output$tid <- renderPrint({
req(lmModel())
tidy(lmModel())
})
output$aug <- renderPrint({
req(lmModel())
augment(lmModel())
})
}
shinyApp(ui, server)
I know it might be duplicated, and I have sought for several questions that is similar with, but I still can not find why my code not work on.
The error occurs when two input sources are compiled to the eventReactive part.
My bug code like this:
library(shiny)
library(rio)
library(DescTools)
options(shiny.maxRequestSize=500*1024^2,shiny.usecairo = FALSE)
ui <- fluidPage(
titlePanel("See the file table"),
fluidRow(
column(4,
fileInput("theFile","upload your file")
),
column(4,
radioButtons("encode", "encoding way",
choices = c("Default" = "default",
"UTF-8" = "utf_8"),selected = "default")
),
column(4,
uiOutput("a_input")
),
column(4,
uiOutput("b_input")
),
column(4,
actionButton("choice3", "Show two variables comparing")
),
column(12,
verbatimTextOutput("console_comp")
),
column(12,
plotOutput("plot_Desc_comp")
)
)
)
server <- function(input,output, session){
allData <- reactive({
theFile <- input$theFile
req(input$theFile)
# Changes in read.table
if(input$encode == "default"){
df <- import(theFile$datapath)
} else{
df <- import(theFile$datapath,encoding = "UTF-8")
return(df)
}
})
output$a_input <- renderUI({
cn <- colnames(allData())
selectInput("a_input", "Select A variable to compare with Desc",
choices = cn,
size=10,
multiple=F, selectize=FALSE)
})
output$b_input <- renderUI({
cn <- colnames(allData())
selectInput("b_input", "Select B variable to compare with Desc",
choices = cn,
size=10,
multiple=F, selectize=FALSE)
})
data_Desc_a <- eventReactive(input$choice3, {
req(allData())
dat <- allData()
dat[,input$a_input, drop = FALSE]
})
data_Desc_b <- eventReactive(input$choice3, {
req(allData())
dat <- allData()
dat[,input$b_input, drop = FALSE]
})
output$console_comp <- renderPrint({
dat <- allData()
var_a <- data_Desc_a()
var_b <- data_Desc_b()
mylist2 <- Desc(var_a ~ var_b, dat)
print(mylist2)
})
output$plot_Desc_comp <- renderPlot({
dat <- allData()
var_a <- data_Desc_a()
var_b <- data_Desc_b()
mylist2 <- Desc(var_a ~ var_b, dat)
plot(mylist2)
})
}
shinyApp(ui, server)
The error code occurs when I want to press the "Show two variables comparing" buttom after I uploaded one file and chose two vars, and the error like this:
unused arguments (var_a ~ var_b, dat)
Even if I just use one source, it can work things out.
My work code like this:
ui <- fluidPage(
titlePanel("See the file table"),
fluidRow(
column(6,
fileInput("theFile","upload your file")
),
column(6,
radioButtons("encode", "encoding way",
choices = c("Default" = "default",
"UTF-8" = "utf_8"),selected = "default")
),
column(8,
uiOutput("colToDesc")
),
column(4,
actionButton("choice2", "Show variables Desc")
),
column(12,
verbatimTextOutput("console")
),
column(12,
plotOutput("plot_Desc")
)
)
)
server <- function(input,output, session){
allData <- reactive({
theFile <- input$theFile
req(input$theFile)
# Changes in read.table
if(input$encode == "default"){
df <- import(theFile$datapath)
} else{
df <- import(theFile$datapath,encoding = "UTF-8")
return(df)
}
})
output$colToDesc <- renderUI({
cn <- colnames(allData())
selectInput("colToDesc", "Select variable to Desc",
choices = cn,
size=10,
multiple=T, selectize=FALSE)
})
data_Desc <- eventReactive(input$choice2, {
req(allData())
dat <- allData()
dat[,input$colToDesc, drop = FALSE]
})
output$console <- renderPrint({
variables <- data_Desc()
mylist <- Desc(variables,main = names(variables))
print(mylist)
})
output$plot_Desc <- renderPlot({
variables <- data_Desc()
mylist <- Desc(variables,main = names(variables))
plot(mylist)
})
}
And I can sure the function of Desc from DescTools package can work well like this :
Desc(temp[,91]~temp[,5],temp)
So what's wrong with my bug code.
I am trying to create a shiny app where depending on the dataset, ggvis will create a scatter plot. The app works fine at the beginning. But if I try to change the dataset to mtcars, shiny just disappears.
My ui.R -
library(ggvis)
library(shiny)
th.dat <<- rock
shinyUI(fluidPage(
titlePanel("Reactivity"),
sidebarLayout(
sidebarPanel(
selectInput("dataset", "Choose a dataset:",
choices = c("rock", "mtcars")),
selectInput("xvar", "Choose x", choices = names(th.dat), selected = names(th.dat)[1]),
selectInput("yvar", "Choose y", choices = names(th.dat), selected = names(th.dat)[2]),
selectInput("idvar", "Choose id", choices = names(th.dat), selected = names(th.dat)[3])
),
mainPanel(
ggvisOutput("yup")
)
)
))
server.R -
library(ggvis)
library(shiny)
library(datasets)
shinyServer(function(input, output, session) {
datasetInput <- reactive({
switch(input$dataset,
"rock" = rock,
"mtcars" = mtcars)
})
obs <- observe({
input$dataset
th.dat <<- datasetInput()
s_options <- list()
s_options <- colnames(th.dat)
updateSelectInput(session, "xvar",
choices = s_options,
selected = s_options[[1]]
)
updateSelectInput(session, "yvar",
choices = s_options,
selected = s_options[[2]]
)
updateSelectInput(session, "idvar",
choices = s_options,
selected = s_options[[3]]
)
})
xvarInput <- reactive({
input$dataset
input$xvar
print("inside x reactive," )
print(input$xvar)
xvar <- input$xvar
})
yvarInput <- reactive({
input$dataset
input$yvar
print("inside y reactive,")
print(input$yvar)
yvar <- input$yvar
})
dat <- reactive({
dset <- datasetInput()
xvar <- xvarInput()
# print(xvar)
yvar <- yvarInput()
# print(yvar)
x <- dset[, xvar]
y <- dset[,yvar]
df <- data.frame(x = x, y = y)
})
dat %>%
ggvis(~x, ~y) %>%
layer_points() %>%
bind_shiny("yup")
})
I have tried many ways, but still stuck. Any help will be greatly appreciated.
I left some pointers in the comments but it seems that ggvis evaluates everything quite early so there is a need for some test cases.
rm(list = ls())
library(shiny)
library(ggvis)
ui <- fluidPage(
titlePanel("Reactivity"),
sidebarPanel(
selectInput("dataset", "Choose a dataset:", choices = c("rock", "mtcars")),
uiOutput("xvar2"),uiOutput("yvar2"),uiOutput("idvar2")),
mainPanel(ggvisOutput("yup"))
)
server <- (function(input, output, session) {
dataSource <- reactive({switch(input$dataset,"rock" = rock,"mtcars" = mtcars)})
# Dynamically create the selectInput
output$xvar2 <- renderUI({selectInput("xvar", "Choose x",choices = names(dataSource()), selected = names(dataSource())[1])})
output$yvar2 <- renderUI({selectInput("yvar", "Choose y",choices = names(dataSource()), selected = names(dataSource())[2])})
output$idvar2 <- renderUI({selectInput("idvar", "Choose id",choices = names(dataSource()), selected = names(dataSource())[3])})
my_subset_data <- reactive({
# Here check if the column names correspond to the dataset
if(any(input$xvar %in% names(dataSource())) & any(input$yvar %in% names(dataSource())))
{
df <- subset(dataSource(), select = c(input$xvar, input$yvar))
names(df) <- c("x","y")
return(df)
}
})
observe({
test <- my_subset_data()
# Test for null as ggvis will evaluate this way earlier when the my_subset_data is NULL
if(!is.null(test)){
test %>% ggvis(~x, ~y) %>% layer_points() %>% bind_shiny("yup")
}
})
})
shinyApp(ui = ui, server = server)
Output 1 for rocks
Output 2 for mtcars