Shiny - two selectInput and one checkbox in one line - r

how to make 2 selectInput and one checkbox in one line, the display will be like this:
x axis : ----- y axis : ------- -check
and the code is :
UI :
library(shiny)
shinyUI(fluidPage(
titlePanel("Shiny"),
sidebarLayout(
sidebarPanel(
),
mainPanel(
uiOutput("scatcoefgwr")
)
)
))
server :
shinyServer(function(input, output) {
output$scatcoefgwr <- renderUI({
list(
selectInput("axisx", "x axis:",choices = c("1","2","3")),
selectInput("axisy", "y axis:",choices = c("1","2","3")),
checkboxInput("scatterD3_ellipsesgwr", "check", value = FALSE)
)
})
})

Here's one way using columns
#ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("Shiny"),
fluidRow(
column(width=2,uiOutput("one")),
column(width=2,uiOutput("two")),
column(width=2,uiOutput("three"))
)
))
change the widths as you need.
#server.R
shinyServer(function(input, output) {
output$one <- renderUI({
list(
selectInput("axisx", "x axis:",choices = c("1","2","3"))
)
})
output$two <- renderUI({
list(
selectInput("axisy", "y axis:",choices = c("1","2","3"))
)
})
output$three <- renderUI({
list(
checkboxInput("scatterD3_ellipsesgwr", "check", value = FALSE)
)
})
})

Related

How to create an editable matrix in Shiny app?

In this code:
library(shiny)
library(shinyMatrix)
if (interactive()) {
# UI
ui <- fluidPage(
selectInput('NumGrig',label = 'Matrix size', choices = c(2:10),selected = 5),
actionButton("add", "Add Martix"),
conditionalPanel(condition = "input.add > 0",
uiOutput("grid"))
)
# Server
server <- function(input, output, session) {
# adding Matrix
observe({
if (!is.null(input$add)) {
m = reactive({matrix('',ncol = input$NumGrig ,nrow = input$NumGrig)})
output$grid <- renderUI({
div(
matrixInput(inputId = "newGrid", value = m()),
actionButton("start", "Convert")
)
})
}
})
}
shinyApp(ui, server)
}
I want to create an editable matrix with prespecified dimension, but I get Error that says:
Error in matrix: non-numeric matrix extent
Why matrixInput is not receiving the input$NumGrig value that was selected in selectInput?
selectInput returns characters : you just have to convert is to numeric with as.numeric.
This works :
library(shiny)
library(shinyMatrix)
if (interactive()) {
# UI
ui <- fluidPage(
selectInput('NumGrig',label = 'Matrix size', choices = c(2:10),selected = 5),
actionButton("add", "Add Matrix"),
conditionalPanel(condition = "input.add > 0",
uiOutput("grid"))
)
# Server
server <- function(input, output, session) {
# adding Matrix
observe({
if (!is.null(input$add)) {
m = reactive({matrix('',ncol = as.numeric(input$NumGrig) ,nrow = as.numeric(input$NumGrig))})
output$grid <- renderUI({
div(
matrixInput(inputId = "newGrid", value = m()),
actionButton("start", "Convert")
)
})
}
})
}
shinyApp(ui, server)
}

How to display the correlation as numeric output in shiny?

I want to select a variable from the data and show the correlation between the selected variable and the variable that selected before. Happiness is my data and score is my selected variable that I choose. I have an error "invalid argument type" Thank you.
shinyApp(
ui = fluidPage(
titlePanel(),
varSelectInput("variable", "Variable:", happiness),
mainPanel(
p(),
p(),
fluidRow(
column(6,plotOutput(outputId="plotgraph1", width="300px",height="300px")),
column(6,plotOutput(outputId="plotgraph2", width="300px",height="300px")),
column(6,tableOutput(outputId="correl.out"))
)
)
),
server = function(input, output) {
output$plotgraph1 <- renderPlot({
ggplot(happiness, aes(x=!!input$variable,y=Score)) + geom_smooth()
})
output$plotgraph2 <- renderPlot({
ggplot(happiness, aes(x=!!input$variable)) + geom_histogram()
})
output$correl.out <- renderTable({
cor(x=!!input$variable,y=happiness$Score)
})
}
)
# We want to use multiple variables to select.
if (FALSE) {
shinyApp(
ui = fluidPage(
varSelectInput("variables", "Variable:", happiness, multiple = TRUE),
tableOutput("data")
),
server = function(input, output) {
output$data <- renderTable({
if (length(input$variables) == 0) return(happiness)
happiness %>% dplyr::select(!!!input$variables)
}, rownames = TRUE)
}
)}
}
)

Using Conditionalpanel Function in Shiny

I'm trying to create the scenario whereby using conditionalpanel, I am able to have an user input of checked boxes to display either 1 or 2 plots, one after another.
My reproducible code can be found below, however, I am unable to display the plots.
Could someone please share with me where did I make a mistake?
library(shiny)
ui = fluidPage(
titlePanel("Plot1 or Plot2?"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("my_choices", "Plot1 or Plot2",choices = c("Plot1", "Plot2"), selected = "Plot1"),width=2),
mainPanel(
conditionalPanel(
condition = "input.my_choices == 'Plot1'",
plotOutput("plot1")
),
conditionalPanel(
condition = "input.my_choices == 'Plot2'",
plotOutput("plot2")
),
conditionalPanel(
condition = "input.my_choices.includes('Plot1', 'Plot2')",
plotOutput("plot1"),
plotOutput("plot2")
)
)
)
)
server = function(input, output) {
output$plot1 <- renderPlot({plot(iris)})
output$plot2 <- renderPlot({plot(mtcars)})
}
shinyApp(ui, server)
Update:
I've got what I wanted but without using ConditionalPanel function. Here's the code below:
Would appreciate if someone can share with me the proper way of using ConditionalPanel Function! (:
library(shiny)
#data
df <- iris
#ui
ui <- fluidPage(
sidebarPanel(
checkboxGroupInput(inputId = "Question",
label = "Choose the plots",
choices = c("Plot1", "Plot2", "Plot3"),
selected = "")),
mainPanel(
uiOutput('ui_plot')
)
)
#server
server <- function(input, output)
{
# gen plot containers
output$ui_plot <- renderUI({
out <- list()
if (length(input$Question)==0){return(NULL)}
for (i in 1:length(input$Question)){
out[[i]] <- plotOutput(outputId = paste0("plot",i))
}
return(out)
})
# render plots
observe({
for (i in 1:3){
local({ #because expressions are evaluated at app init
ii <- i
output[[paste0('plot',ii)]] <- renderPlot({
if ( length(input$Question) > ii-1 ){
return(plot(runif(100)))
}
NULL
})
})
}
})
}
shinyApp(ui, server)
I would give you an alternative as you will need to create new plots with different id in order for that to work. The simplest one I can think of is using shinyjs package and its hide and show functions. You can also do this via renderUI but you shouldn't give unnecessary work to your server only if you're showing and hiding the elements
library(shiny)
library(shinyjs)
ui = fluidPage(
useShinyjs(),
titlePanel("Plot1 or Plot2?"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("my_choices", "Plot1 or Plot2",choices = c("Plot1", "Plot2"), selected = "Plot1"),width=2),
mainPanel(
plotOutput("plot1"),
plotOutput("plot2")
)
)
)
server = function(input, output,session) {
# hide plots on start
hide("plot1");hide("plot2")
output$plot1 <- renderPlot({plot(iris)})
output$plot2 <- renderPlot({plot(mtcars)})
observeEvent(input$my_choices,{
if(is.null(input$my_choices)){
hide("plot1"); hide("plot2")
}
else if(length(input$my_choices) == 1){
if(input$my_choices == "Plot1"){
show("plot1");hide("plot2")
}
if(input$my_choices == "Plot2"){
hide("plot1");show("plot2")
}
}
else{
if(all(c("Plot1","Plot2") %in% input$my_choices)){
show("plot1");show("plot2")
}
}
},ignoreNULL = F)
}
shinyApp(ui, server)

show an unknown number of graphs in a grid RShiny

I have looked at all the solutions on SO using grid.arrange but it doesn't really achieve what I want.
Let's assume I have a list of grobs that are generated within a reactive environment in RShiny.
I would like to create a mainPanel where those graphs are on 2 columns (until that point, it's all feasible with grid.arrange) but where each line corresponds to a fluidRow element.
A barebone example of this would be
ui <- fluidPage(
titlePanel("TEST"),
sidebarPanel(width=3,
actionButton(inputId = 'launchCalcButton',label = 'Launch Calc')
),
mainPanel(
uiOutput("resultsPlotUI")
)
)
server <- function(input,output){
graphsList <- eventReactive(input$launchCalcButton, {
a <- lapply(1:10,function(i){
return(
ggplot(data = data.frame(a=rnorm(10),b=rnorm(10)),aes(x=a,y=b))
+geom_point()
)
})
return(a)
})
output$resultsPlot <- renderPlot({
do.call(grid.arrange,c(graphsList(),ncol=2))
})
output$resultsPlotUI <- renderUI({
fluidRow(
column(12,
plotOutput(
outputId = 'resultsPlot'
)
)
)
})
}
app = shinyApp(ui,server)
runApp(app)
All the graphs end up squeezed into one single line whereas I would want them to be split between lines.
You just need to set up height parameter for the plotOutput:
library(shiny)
library(gridExtra)
ui <- fluidPage(
titlePanel("TEST"),
sidebarPanel(width=3,
actionButton(inputId = 'launchCalcButton',label = 'Launch Calc')
),
mainPanel(
uiOutput("resultsPlotUI")
)
)
server <- function(input,output){
graphsList <- eventReactive(input$launchCalcButton, {
a <- lapply(1:10,function(i){
return(
ggplot(data = data.frame(a=rnorm(10),b=rnorm(10)),aes(x=a,y=b))
+geom_point()
)
})
return(a)
})
output$resultsPlot <- renderPlot({
l <- length(graphsList())/2
print(l)
do.call(grid.arrange,c(graphsList(),ncol=2))
})
output$resultsPlotUI <- renderUI({
fluidRow(
column(12,
plotOutput(
outputId = 'resultsPlot', height = 600
)
)
)
})
}
app = shinyApp(ui,server)
runApp(app)
Exactly in this place:
output$resultsPlotUI <- renderUI({
fluidRow(
column(12,
plotOutput(
outputId = 'resultsPlot', height = 600
)
)
)
})
I have set it up to 600 px (height = 600) but you can choose whatever you want.

Dealing with loop, fluidRow and column in shiny

I'm trying to make a Shiny application that display multiple plots on different rows and allow user to select the proper tendencies by using the radioButtons situated beside the graph. The problem is that I'm not able to get the radioButtons located directly beside the plots.
I want:
And I get:
My code:
server.R:
library(shiny)
shinyServer(function(input, output) {
lapply(1:3, function(iter) {
output[[paste0("g",iter)]] <- renderPlot({
set.seed(iter)
xx <- rnorm(10)
yy <- rnorm(10)
plot(xx,yy)
abline(reg=lm(yy~xx), col=2, lwd=ifelse(input[[paste0("radio",iter)]]==1,2,1))
abline(reg=lm(yy~xx+0), col=3, lwd=ifelse(input[[paste0("radio",iter)]]==2,2,1))
})
})
})
ui.R:
library(shiny)
shinyUI(fluidPage(
titlePanel("My loop test"),
fluidRow(
column(6,
lapply(1:3, function(iter) {
plotOutput(paste0("g",iter))
}
)),
column(3,
lapply(1:3, function(iter){
radioButtons(paste0("radio",iter),label = "buttons", choices = list("with intercept"=1,"without intersept"=2),selected = 1)
}
))
)
))
I hope it's clear. I'm new to Shiny (but not R) and I'm still in the steep part of the learning curve!
Thanks
Maybe something like this:
shinyUI(fluidPage(
titlePanel("My loop test"),
lapply(1:3, function(iter) {
fluidRow(
column(
6,
plotOutput( paste0("g",iter) )
),
column(
3,
radioButtons(
paste0("radio", iter),
label = "buttons",
choices = list("with intercept"=1,"without intersept"=2),
selected = 1)
)
)
})
))
This is a good use case for modules. I didn't get the buttons to line up perfectly, but that could be fixed with some CSS:
library(shiny)
myModUI <- function(id) {
ns <- NS(id)
tagList(
fluidRow(
splitLayout(cellWidths=c("75%","25%"),
plotOutput(ns("g")),
radioButtons(ns("radio"),label = "buttons",
choices = list("with intercept"=1,"without intersept"=2),
selected = 1))
)
)
}
myMod <- function(input, output, server, seed) {
output$g <- renderPlot({
set.seed(seed)
xx <- rnorm(10)
yy <- rnorm(10)
plot(xx,yy)
abline(reg=lm(yy~xx), col=2, lwd=ifelse(input$radio==1,2,1))
abline(reg=lm(yy~xx+0), col=3, lwd=ifelse(input$radio==2,2,1))
})
return(reactive(input$radio))
}
server <- shinyServer(function(input, output, server) {
lapply(1:5,function(i) {
callModule(myMod,i,seed=i)
})
})
ui <- shinyUI(fluidPage(
titlePanel("My loop test"),
mainPanel(
lapply(1:5,function(i) {
myModUI(i)
})
)
))
shinyApp(ui=ui,server=server)
Note that fluidRow isn't enough, we have to use splitLayout

Resources