I have a vector with sequence of elements. I'm trying to provide two selectInput for the user to choose elements/variables from the vector, such that the element selected in the first is excluded from second selectInput.
I tried to remove the selected element based on index from the sequence of second selectInput, but the output was only one element, instead of all the remaining list of elements.
I couldn't understand why. Can someone help me?
Thank you in advance.
Below is the code:
data <- c("cultivar","control", "stress")
ui <- fluidPage(
selectInput("select1", "Select variable", choices = data),
uiOutput("UiSelect2")
)
server <- function(input, output, session) {
output$UiSelect2 <- renderUI({
#remove the selected element based on index
newData <- data[-which(data == input$select1)]
selectInput("select2","Select another variable", choices= ifelse(isTruthy(input$select1), newData, data))
})
}
shinyApp(ui, server)
Is this what you want?
library(shiny)
data <- c("cultivar","control", "stress")
ui <- fluidPage(
selectInput("select1", "Select variable", choices = data),
uiOutput("UiSelect2")
)
server <- function(input, output, session) {
output$UiSelect2 <- renderUI({
#remove the selected element based on index
newData <- data[!data %in%input$select1]
selectInput("select2","Select another variable", choices = newData)
})
}
shinyApp(ui, server)
Related
How to display the entire row of a selected value?
What we have is a drop down menu where a certain values of a defined column can be selected. If one of the values in the the drop down menu is selected the entire row where this value is located should be displayed.
In the following case the values that can be selected in a drop down menu are the letters x, y, z. e.g. If "y" is selected in the drop down menu, it should be displayed only the entire second row inlcuding the column names.
library(shiny)
Values <- data.frame(A = 1:3, B = letters[24:26], C = 11:13)
shinyApp(
ui = fluidPage(
sidebarPanel(
selectInput("Values", "Values", Values$B),
mainPanel(
tableOutput("ValuesTable")
)
)
),
server = function(input, output) {
output$ValuesTable <- renderTable({
Values
})
})
What I´ve found so far are solutions with _rows_selected. However, it doesn´t fit to my problem or I´m not able to make use of it, yet.
You can filter values in the appropriate column using dplyr::filter() with your select input "Values" in the renderTable() function.
library(shiny)
library(dplyr) # for filter() function
library(magrittr) # for pipe operator
Values <- data.frame(A = 1:3, B = letters[24:26], C = 11:13)
shinyApp(
ui = fluidPage(
sidebarPanel(
selectInput("Values", "Values", Values$B),
mainPanel(
tableOutput("ValuesTable")
)
)
),
server = function(input, output) {
output$ValuesTable <- renderTable({
Values %>%
dplyr::filter(B == input$Values)
})
})
I would like to update column headers in an R Shiny proxy table. The app should:
Launch with original column header names (e.g. "Do","Re","Mi","Fa","So")
Change those column headers in the proxy table to something else when the user clicks an action button (e.g. "y1","y2","y3","y4","y5")
Shiny has a convenient updateCaption() method that allows for a similar behavior for proxy table captions. I'd like to do something similar with table column headers for proxy tables. Here's my attempt.
library(shiny)
library(DT)
ui <- fluidPage(
fluidRow(
actionButton(
"updatebutton",
label = "Update Table",
style = "margin-right: 5px;"
),
DT::dataTableOutput("myplot")
),
)
server <- function(input, output) {
mycolumnnames <-c("Do","Re","Mi","Fa","So")
myothercolumnnames <- c("y1","y2","y3","y4","y5")
output$myplot <- DT::renderDataTable({
DF <- data.frame(replicate(5, sample(rnorm(5), 10, rep = TRUE)))
datatable(DF, colnames = mycolumnnames,
caption="Original caption")
})
proxy <- DT::dataTableProxy("myplot")
observeEvent(input$updatebutton, {
updateCaption(proxy, caption="Look, I am a NEW caption!")
DF <- data.frame(replicate(5, sample(rnorm(5), 10, rep = TRUE)))
# names(DF) <- myothercolumnnames # This doesn't work
proxy %>% replaceData(DF)
})
}
shinyApp(ui = ui, server = server)
Edit1: Now uses dataTableProxy()
I took away all the things related to color background so I could focus on your problem.
First, I declare some values outside shiny: your data.frame and two vectors for the column names. Then I assign the column names as the first vector.
Inside the app, I retrieve the data as a reactiveVal(), and update its colnames whenever the button is pressed
library(shiny)
library(DT)
mycolumnnames <-c("Do","Re","Mi","Fa","So")
myothercolumnnames <- c("y1","y2","y3","y4","y5")
DF <- data.frame(replicate(5, sample(rnorm(5), 10, rep = TRUE)))
colnames(DF) <- mycolumnnames
ui <- fluidPage(
fluidRow(
actionButton(
"updatebutton",
label = "Update Table",
style = "margin-right: 5px;"
),
DT::dataTableOutput("myplot")
),
)
server <- function(input, output) {
df <- reactiveVal(DF)
output$myplot <- DT::renderDataTable({
datatable(df(), caption="Original caption")
})
observeEvent(input$updatebutton, {
new_data <- data.frame(replicate(5, sample(rnorm(5), 10, rep = TRUE)))
if(!input$updatebutton %% 2 == 0 ){
colnames(new_data) <- myothercolumnnames
} else {
colnames(new_data) <- mycolumnnames
}
df(new_data)
proxy1 <- DT::dataTableProxy("myplot")
updateCaption(proxy1, caption="Look, I am a NEW caption!")
replaceData(proxy1, df())
})
}
shinyApp(ui = ui, server = server)
So whenever you press the button, the colnames are changed between the two vectors.
I am working with global variables that update after time X. This issue I am coming across is it updates the global variable but the current session doesn't update accordingly, however, any new session open uses the updated global variable.
Question: how do I get the current session to use the updated global variable? I thought wrapping it in a reactive would work but it doesn't.
Code:
library(shiny)
library(shinydashboard)
####/GLOBAL/####
num <- 4
####/UI/####
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody(
verbatimTextOutput("test")
)
ui <- dashboardPage(header, sidebar, body)
####/SERVER/####
server <- function(input, output, session) {
data <- reactive({num})
output$test <- renderText({ data() })
observe({
invalidateLater(0.5*60*1000,session)
num <<- sample(1:1000,1,replace=T)
})
}
shinyApp(ui, server)
If you wait 30+ seconds and then open up a new session you will see that the number has changed from 4 but the original session still shows 4. They should be showing the same number.
Solved! Realized I needed to wrap it in a reactiveValues versus reactive. I also made the updating a value a dataframe versus a single number because that fits my real dashboard's problem.
library(shiny)
library(shinydashboard)
####/GLOBAL/####
dataset <- data.frame(ColA = c("dogs", "cats", "birds"), ColB = c(10, 2, 2), stringsAsFactors = FALSE)
####/UI/####
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody(
box(width = 3, tableOutput("test"))
)
ui <- dashboardPage(header, sidebar, body)
####/SERVER/####
server <- function(input, output, session) {
values <- reactiveValues(n = dataset)
data <- reactive({values$n})
output$test <- renderTable({ data() })
observe({
invalidateLater(0.5*60*1000,session)
new1 <- sample(1:10,1,replace=T)
new2 <- sample(1:10,1,replace=T)
new3 <- sample(1:10,1,replace=T)
print(new1)
print(new2)
print(new3)
dat <- data.frame(ColA = c("dogs", "cats", "birds"), ColB = c(new1, new2, new3), stringsAsFactors = FALSE)
values$n <- dat
dataset <<- dat
})
}
shinyApp(ui, server)
I would like to add a checkbox (input$autorefresh) in my shiny application to control where my data input is auto updated (=reactive()) at every change, or whether it is only updated when a button (=input$refresh) is pushed. The idea is described in the following code, which I however didn't expect to work. I could use reactive() together with a conditional isolate(), but since I have many inputs, that is not very elegant. Any ideas?
if (input$autorefresh==TRUE){
dataInput <- reactive({
dosomething
})
} else {
dataInput <- eventReactive(input$refresh,{
dosomething
})
}
Are you looking for something like this?
library(shiny)
ui <- fluidPage(
checkboxInput("autorefresh","autorefresh", F),
actionButton("refresh","refresh"),
mainPanel(plotOutput("plot"))
)
autoInvalidate <- reactiveTimer(1000)
server <- function(input, output, session) {
data <- reactive({
input$refresh
data <- plot(rnorm(100),type="l",col="red")
if(input$autorefresh){
autoInvalidate()
return(data)
}
return(data)
})
output$plot <- renderPlot({
data()
})
}
runApp(shinyApp(ui = ui, server = server))
I am attempting to run a regression that allows users to determine regression inputs, and then provide an output that is the regression summary. For whatever reason, the output is not coming out correct, and I have looked everyone on the internet to find a solution. I am hoping somebody can help.
For clarification, this is in shiny.
Here is my server code:
shinyServer(
function(input,output,session) {
mod <- eventReactive(input$analysis,{
response <- data[,2]
explan1 <- data[,input$Explan1]
explan2 <- data[,input$Explan2]
explan3 <- data[,input$Explan3]
mod1 <- lm(response~explan1+explan2+explan3)
} )
output$modelSummary <- renderPrint({
(summary(mod()$mod1))
})
output$ColumnNames <- renderPrint({
as.data.frame(colnames(data))
})
}
)
summary(model)
And my ui code
shinyUI(
fluidPage(
titlePanel("What does it take for a Hockey Team to Win?"),
titlePanel("Please select the column numbers for three variables to regress on"),
sidebarLayout(
sidebarPanel(
verbatimTextOutput("ColumnNames"),
numericInput("Explan1","Explanatory Variable 1",3,min = 3, max = 13),
numericInput("Explan2","Explanatory Variable 2",4,min = 3,max = 13),
numericInput("Explan3","Explanatory Variable 3",5,min = 3, max = 13)
),
mainPanel(
actionButton("analysis","Analyze!"),
verbatimTextOutput("modelSummary")
)
)
)
)
When I run the app, select the input columns (which are by number rather than name. I hope to fix this later) and click analyze, I get the following output:
Length Class Mode
0 NULL NULL
I haven't been able to find much relevant information on this output. I hope you all can help.
Thank you in advance.
You're just calling the reactive incorrectly, it should be: summary(mod()) instead of summary(mod()$mod1). Reactives behave very much like functions the way that they return objects.
Here is a fully reproducible example, with an example on how to use a formula instead of individually selecting the columns:
col_names <- names(mtcars)
ui <- fluidPage(
sidebarPanel(
verbatimTextOutput("ColumnNames"),
selectInput("Response", "Response Variable", choices = col_names, selected = "mpg"),
selectInput("Explan1","Explanatory Variable 1", choices = col_names, selected = "cyl"),
selectInput("Explan2","Explanatory Variable 2", choices = col_names, selected = "disp"),
selectInput("Explan3","Explanatory Variable 3", choices = col_names, selected = "wt")
),
mainPanel(
actionButton("analysis","Analyze!"),
verbatimTextOutput("modelFormula"),
verbatimTextOutput("modelSummary")
)
)
server <- function(input, output, session) {
myformula <- reactive({
expln <- paste(c(input$Explan1, input$Explan2, input$Explan3), collapse = "+")
as.formula(paste(input$Response, " ~ ", expln))
})
mod <- eventReactive(input$analysis, {
lm(myformula(), data = mtcars)
})
output$modelFormula <- renderPrint({
myformula()
})
output$modelSummary <- renderPrint({
summary(mod())
})
}
shinyApp(ui, server)
Screenshot: