I would like to perform multiple linear regression in a shiny app but every time I would like to change dependent and independent variables based on 2 shiny widgets. Could this be achieved?
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
library(dplyr)
shinyApp(
ui = dashboardPagePlus(
header = dashboardHeaderPlus(title = "Social Media Metrics", titleWidth = 320
),
sidebar = dashboardSidebar(width = 320,
uiOutput("value"),
uiOutput("value2")
),
body = dashboardBody(
verbatimTextOutput("plot")
)
),
server = function(input, output) {
output$value<-renderUI({
pickerInput(
inputId = "val"
,
label = "DEPENDENT"
,
choices = colnames(iris)[-5] #all rows of selected column
,
multiple = F, options = list(`actions-box` = TRUE)
)
})
output$value2<-renderUI({
pickerInput(
inputId = "val2"
,
label = "INDEPENDENT"
,
choices = colnames(iris)[-5] #all rows of selected column
,
multiple = T, options = list(`actions-box` = TRUE)
)
})
output$plot<-renderPrint({
model <- lm(input$val ~ input$val2, data = iris)
summary(model)
})
}
)
Sure, you can access it like so:
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
library(dplyr)
shinyApp(
ui = dashboardPagePlus(
header = dashboardHeaderPlus(title = "Social Media Metrics", titleWidth = 320
),
sidebar = dashboardSidebar(width = 320,
uiOutput("value"),
uiOutput("value2")
),
body = dashboardBody(
verbatimTextOutput("plot")
)
),
server = function(input, output) {
output$value<-renderUI({
pickerInput(
inputId = "val"
,
label = "DEPENDENT"
,
choices = colnames(iris)[-5] #all rows of selected column
,
multiple = F, options = list(`actions-box` = TRUE)
)
})
output$value2<-renderUI({
pickerInput(
inputId = "val2"
,
label = "INDEPENDENT"
,
choices = colnames(iris)[-5] #all rows of selected column
,
multiple =T, options = list(`actions-box` = TRUE)
)
})
model <- eventReactive(c(input$val,input$val2),{
req(c(input$val,input$val2))
lm(as.formula(paste(input$val," ~ ",paste(input$val2,collapse="+"))),data=iris)
})
output$plot <- renderPrint({
summary(model())
})
}
)
Related
I'm trying to format my datatable output. I want to make some changes to the table format (e.g, hide the row names) and hide columns (e.g., hide gears and carb, which I use to filter the datatable). I've read through this response before, but can't seem to get it to work. Does anyone have any suggestions for me?
I've prepared reproducible code below. In a nutshell, I'm using the mtcars dataset (my actual dataset is longer). Users can set filters, and the table output will update accordingly. It's this part of the code (under server) that isn't working:
class = "display nowrap compact"
#filter = "top" # location of column filters
filter = list(position = "top")
rownames = TRUE
options = list(dom = 't',
scrollX = TRUE # allow user to scroll wide tables horizontally
)
Full code here:
library(tidyverse)
library(shiny)
library(dplyr)
library(ggplot2)
library(tidyr)
library(shinycssloaders)
library(shinythemes)
library(ggforce)
library(DT)
library(shinyWidgets)
library(shinyjs)
mtcars
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
useShinyjs(),
div(
id = "form",
fluidRow(
#Button to select gear
column(6,
pickerInput(
inputId = "gear_button", label = "Gear:", choices = c("All", unique(as.character(mtcars$gear))), options = list(`actions-box` = TRUE), multiple = FALSE
),
),
#Button to select carb ranges
column(6,
pickerInput(inputId = "carb_button", label = "Carb:", choices = c("All", unique(as.character(mtcars$carb))), options = list(`actions-box` = TRUE), multiple = FALSE
),
),
)),
actionButton("resetAll", "Reset Filters")
),
mainPanel(
DT::dataTableOutput("table")
)
),
)
server <- function(input, output, session) {
#Explore tab - table
data <- mtcars
output$table <- DT::renderDataTable(DT::datatable({
data
class = "display nowrap compact"
#filter = "top" # location of column filters
filter = list(position = "top")
rownames = TRUE
options = list(dom = 't',
scrollX = TRUE # allow user to scroll wide tables horizontally
)
if (input$gear_button != "All") {
data <- data[data$gear == input$gear_button,]
}
if (input$carb_button != "All") {
data <- data[data$carb == input$carb_button,]
}
data
}))
observeEvent(input$resetAll, {
reset("form")
})
}
shinyApp(ui, server)
We can use
options= list(columnDefs = list(list(visible = FALSE, targets = target)))
to control which columns are visible, and
target <- which(names(mtcars) %in% c("gear", "carb")) - 1
to get the position of the cols. The - 1 is because js uses 0 index instead of 1 like R.
App:
library(tidyverse)
library(shiny)
library(dplyr)
library(ggplot2)
library(tidyr)
library(shinycssloaders)
library(shinythemes)
library(ggforce)
library(DT)
library(shinyWidgets)
library(shinyjs)
mtcars
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
useShinyjs(),
div(
id = "form",
fluidRow(
# Button to select gear
column(
6,
pickerInput(
inputId = "gear_button", label = "Gear:", choices = c("All", unique(as.character(mtcars$gear))), options = list(`actions-box` = TRUE), multiple = FALSE
),
),
# Button to select carb ranges
column(
6,
pickerInput(inputId = "carb_button", label = "Carb:", choices = c("All", unique(as.character(mtcars$carb))), options = list(`actions-box` = TRUE), multiple = FALSE),
),
)
),
actionButton("resetAll", "Reset Filters")
),
mainPanel(
DT::dataTableOutput("table")
)
),
)
server <- function(input, output, session) {
# Explore tab - table
data <- mtcars
table <- reactive({
if (input$gear_button != "All") {
data <- data[data$gear == input$gear_button, ]
}
if (input$carb_button != "All") {
data <- data[data$carb == input$carb_button, ]
}
data
})
output$table <- DT::renderDataTable({
target <- which(names(table()) %in% c("gear", "carb")) - 1
datatable(table(),
class = "display nowrap compact",
filter = list(position = "top"),
rownames = FALSE,
options = list(
dom = "t",
columnDefs = list(list(visible = FALSE, targets = target)),
scrollX = TRUE
)
)
})
observeEvent(input$resetAll, {
reset("form")
})
}
shinyApp(ui, server)
I am trying to create a dynamic left menu (header), but the items are listed downward instead of to the right. I guess it has to do with the tagList wrapper when defining the UI.
library(shiny)
library(shinydashboard)
library(shinydashboardPlus)
library(shinyWidgets)
library(stringr)
ui = dashboardPage(
dashboardHeader(
leftUi = tagList(uiOutput("filter"))
),
dashboardSidebar(
pickerInput(
"inputParameters",
"Parameters:",
choices = c("a", "b", "c"),
multiple = TRUE,
options = list(
`actions-box` = TRUE,
size = 10,
`selected-text-format` = "count > 1"
)
)
),
dashboardBody(),
title = "DashboardPage"
)
server = function(input, output) {
params <- reactive(input$inputParameters)
output$filter = renderUI(
lapply(seq_along(params()), function(i) {
dropdownButton(
inputId = paste0("mydropdown", i),
label = params()[i],
icon = icon("sliders"),
status = "primary",
circle = FALSE,
selectizeInput(
paste0("input", paste0(str_to_title(params()[i]))),
paste0(paste0(str_to_title(params()[i]), ":")),
choices = 1:3,
multiple = TRUE,
selected = 1:3
)
)
})
)
}
shinyApp(ui, server)
Not tested, I would try:
output$filter = renderUI({
ddbuttons <- lapply(seq_along(params()), function(i) {
dropdownButton(
inputId = paste0("mydropdown", i),
label = params()[i],
icon = icon("sliders"),
status = "primary",
circle = FALSE,
selectizeInput(
paste0("input", paste0(str_to_title(params()[i]))),
paste0(paste0(str_to_title(params()[i]), ":")),
choices = 1:3,
multiple = TRUE,
selected = 1:3
)
)
})
do.call(splitLayout, ddbuttons)
})
And don't use tagList, just uiOutput("filter").
I am able to render a datatable in my shiny app. However, whenever there is a wide table, the horizontal scroller gets back to it's initial position when you apply filters on the columns in the back. This issue occurs with numeric columns only.
I was wondering if there is a way I can disable range-based filters (but keep the filters itself) or if there is any other workaround for this problem.
I have searched github issues and stackoveflow prior to posting this question here since I couldn't find anybody having this problem.
Here is a reproducible example along with pictures-
options(scipen = 99999) #converts the sci numbers to their regular format
library(shiny)
library(shinyjs)
library(shinyWidgets)
library(shinythemes)
library(writexl)
library(dplyr)
library(DT)
library(dplyr)
mtcars_modified <- mtcars %>% dplyr::mutate(wt_2= wt,
qsec_2 = qsec,
am_2= am,
mpg_2= mpg,
gear_2 = gear,
carb_2 = carb,
disp_2 = disp,
row_names_col= rownames(mtcars))
ui <- fluidPage(
theme = shinythemes::shinytheme("simplex"),
shinyjs::useShinyjs(), # enables javascript/jQuery enhanchments
# Create Right Side Text
navbarPage(
id = "navbar",
title= div(HTML("G<em>T</em>")),
#windowTitle = "GT",
tabPanel("Data Set Info",
materialSwitch(inputId = "toggleSidebar", label = "Toggle Panel: ",
value = TRUE, status = "warning"),
sidebarLayout(
# radio/action buttons
sidebarPanel(
id = "Sidebar",
prettyRadioButtons(
inputId = "controller",
label = "Choose:",
choices = c("About"= 1,
"iris"= 2,
"mtcars_modified" = 3),
icon= icon("check"),
selected = 1,
status = "success",
animation="smooth"
),
br(),
br()
),
#panel where output is shown from server
mainPanel(
id = "main_panel",
tabsetPanel(
id = "hidden_tabs",
type = "hidden",
tabPanelBody(
"panel1", "navigation"
),
tabPanelBody(
"panel2",
tabsetPanel(
tabPanel("Data", DT::DTOutput('panel1_data')),
tabPanel("Summary", verbatimTextOutput("panel1_sum")),
tabPanel(
"Plot"
)
)
),
tabPanelBody(
"panel3",
tabsetPanel(
tabPanel("Data", DT::DTOutput('panel3_data')),
tabPanel("Summary", verbatimTextOutput("panel3_sum")),
tabPanel(
"Plot"
)
)
)
)
)
)
) ,
#resizes the navbar tabs/button
tags$head(tags$style(HTML('.navbar-brand {width: 270px; font-size:35px; text-align:left;
font-family: "serif";')))
)
)
server <- function(input, output, session) {
# this event hides the side panel when toggled on/off
observeEvent(input$toggleSidebar, {
shinyjs::toggle(id = "Sidebar", condition = input$toggleSidebar)
if(!isTRUE(input$toggleSidebar)) {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-8').addClass('col-sm-12')")
} else {
shinyjs::runjs("$('#main_panel').removeClass('col-sm-12').addClass('col-sm-8')")
}
})
# here we put all the data
data_sets <- list(df1 = data.frame(),
df2= iris,
df3 = mtcars_modified)
# store current dataset in reactive so we can work with plot panels
data_to_use <- reactiveValues(name = "df", data = data.frame())
observeEvent(input$controller, {
# skip first panel since it is used to display navigation
updateTabsetPanel(session, inputId= "hidden_tabs", selected = paste0("panel", input$controller))
# enswure value is avilable throught selected tabSet
req(input$controller)
# get current data and df name
data_to_use$data <- data_sets[[as.numeric(input$controller)]]
data_to_use$name <- names(data_sets[as.numeric(input$controller)])
# update table and sum
output[[paste0('panel', input$controller, '_data')]] <-
DT::renderDT(server = FALSE, {
DT::datatable(data_to_use$data,
filter = 'top',
extensions = 'Buttons',
options = list(scrollY = 600,
scrollX = TRUE,
dom = '<"float-left"l><"float-right"f>rt<"row"<"col-sm-4"B><"col-sm-4"i><"col-sm-4"p>>',
lengthMenu= list(c(10, 25, 50, -1),
c('10', '25', '50','All')),
buttons = list(
list(extend = "collection", text = "Download",
filename = "data_excel",
exportOptions = list(
modifier = list(page = "all")
),
action = DT::JS("function ( e, dt, node, config ) {
Shiny.setInputValue('Download_DATA', true, {priority: 'event'});}"
)
)
),
scrollCollapse= TRUE,
lengthChange = TRUE,
widthChange= TRUE,
rownames = TRUE))})
output[[paste0('panel', input$controller, '_sum')]] <- renderPrint(summary(data_to_use$data))
})
}
#runs the app
shinyApp(ui= ui, server= server)
The process_map() function in the server in the R shiny script creates the diagram image as below. My requirement is that there are two attributes "FUN" and "units" that are part of the performance() function. They have standard four values each that are available in the ui code below under PickerInput ID's Case4 and Case5. Currently, I am hard coding the value to create the map, can you help me to use the id's in the server code and make it dynamic such that when I select the value in the PickerInput, the formula fetches the value directly. Thanks and please help.
library(shiny)
library(shinydashboard)
library(bupaR)
library(processmapR)
library(lubridate)
library(dplyr)
library(edeaR)
library(shinyWidgets)
library(DiagrammeR)
ui <- dashboardPage(
dashboardHeader(title = "Diagram Plot",titleWidth = 290),
dashboardSidebar(width = 0),
dashboardBody(
tabsetPanel(type = "tab",
tabPanel("Overview", value = 1,
box(
column(1,
dropdown(
pickerInput(inputId = "resources",
label = "",
choices = c("Throughput Time"),
choicesOpt = list(icon = c("fa fa-bars",
"fa fa-bars",
"fa fa-safari")),
options = list(`icon-base` = "")),
circle = FALSE, status = "primary", icon = icon("list", lib = "glyphicon"), width = "300px"
),
conditionalPanel(
condition = "input.resources == 'Throughput Time' ",
tags$br(),
tags$br(),
tags$br(),
dropdown(
pickerInput(inputId = "Case4",
label = "Select the Process Time Summary Unit",
choices = c("min","max","mean","median"), options = list(`actions-box` = TRUE),
multiple = F),
circle = FALSE, status = "primary", icon = icon("eye-close", lib = "glyphicon"), width = "300px"
),
tags$br(),
tags$br(),
tags$br(),
dropdown(
pickerInput(inputId = "Case5",
label = "Select the Process Time Unit",
choices = c("mins","hours","days","weeks"), options = list(`actions-box` = TRUE),
multiple = F, selected = "days"),
circle = FALSE, status = "primary", icon = icon("eye-close", lib = "glyphicon"), width = "300px"
))),
title = "Process Map",
status = "primary",height = "575", width = "500",
solidHeader = T,
column(10,grVizOutput("State")),
align = "left")
),
id= "tabselected"
)))
server <- function(input, output) {
output$State <- renderDiagrammeR(
{
if(input$resources == "Throughput Time")
patients %>% process_map(performance(FUN = mean,units = "days"))
else
return()
})}
shinyApp(ui, server)
test this:
output$State <- renderDiagrammeR({
if(input$resources == "Throughput Time")
{
if(input$Case4=="mean"){
patients %>% process_map(performance(FUN = mean,units = input$Case5))}
else if(input$case4=="min"){
patients %>% process_map(performance(FUN = min,units = input$Case5))
}else if(input$case4=="max"){
patients %>% process_map(performance(FUN = max ,units = input$Case5))
}else{
patients %>% process_map(performance(FUN = median ,units = input$Case5))
}
}else
return()
})
or you can use this:
patients %>%
process_map(performance(FUN = eval(parse(text=input$Case4)) ,units = input$Case5))
enjoy;)
here is a sample:
library(shiny)
ui <- fluidPage(
selectInput(inputId = "func", label = "Choose The Function", choices = c("mean", "sum", "median"))
,
textOutput("text")
)
server <- function(input, output, session) {
main_data <- reactive({
data.frame(a= rnorm(100), b=rnorm(100) )
})
output$text <- renderText({
df <- main_data()
apply(df,2, FUN = eval(parse(text=input$func)) )
})
}
shinyApp(ui = ui, server = server)
You could use do.call to call a function from its name, see the example below. You can add arguments by adding them in the list in the do.call function, e.g. list(x,units=input$Case5).
library(shiny)
x=c(1,2,3,4,5,6,7)
ui <- fluidPage(
selectInput('select','Select Function: ', choices=c('mean','max','min','median')),
textOutput('text')
)
server <- function(input,output)
{
output$text <- renderText({
result = do.call(input$select, list(x))
paste0('The ', input$select, ' of [', paste(x,collapse=', '),'] is ', result)
})
}
shinyApp(ui,server)
Hope this helps!
I am working on a Shiny App that uses rhandsontable and I would like to provide the user an option to save and load the progress. A minimal example of my code is as follows:
library(shinydashboard)
library(shiny)
library(data.table)
library(rhandsontable)
library(markdown)
sidebar <- dashboardSidebar(
sidebarMenu(
menuItem("Data", tabName = "data", icon = icon("file")),
menuItem("Control", tabName = "control", icon = icon("list-alt"))
)
)
body <- dashboardBody(
tabItems(
tabItem(tabName = "data",
fluidRow(
box(title = h3("Input data manually or by importing a .csv file:"),
#fileInput("file1", "Choose CSV File:", width = '30%',
# multiple = TRUE,
# accept = c("text/csv",
# "text/comma-separated-values,text/plain",
# ".csv")),
width = 12, height = 800, rHandsontableOutput("hot"))
)
),
tabItem(tabName = "control",
fluidRow(
actionButton("save", "Save"), actionButton("load", "Load"),
box(title = h2("1. General Information"), width = '100%',
radioButtons("Type",
h4("Type:"),
choices = list("1" = "1", "2" = "2")),
radioButtons("DataExtraction",
h4("Extract information:"),
choices = list("Yes" = "Yes", "No" = "No"), selected = "No")
)
)
)
)
)
ui <- dashboardPage(
dashboardHeader(title = "Shiny"),
sidebar,
body
)
server <- function(input, output, session) {
observeEvent(input$load,{
values <<- readRDS("C:/Documents/ws1.RData")
if (exists("values")) {
lapply(names(values),
function(x) session$sendInputMessage(x, list(value = values[[x]]))
)
}
})
observeEvent(input$save,{
values <<- lapply(reactiveValuesToList(input), unclass)
saveRDS( values , file = "C:/Documents/ws1.RData")
})
filedata <- reactive({
inFile <- input$file1
if (is.null(inFile)){
data.table(Number1 = numeric(20),
Number2 = numeric(20),
Date1 = seq(from = Sys.Date(), by = "days", length.out = 20),
Date2 = seq(from = Sys.Date(), by = "days", length.out = 20))
} else{
fread(input$file1$datapath)
}
})
output$hot = renderRHandsontable({
rhandsontable(filedata()) %>%
hot_cols(columnSorting = TRUE) %>%
hot_table(highlightCol = TRUE, highlightRow = TRUE)
})
}
shinyApp(ui, server)
I am encountering two issues:
When I include the fileInput("file1", ...), the inputs do not update
anymore once I click the load action button;
The Rhandsontable is not updated. However, when I look into values$hot$data, it does seem as if the data is properly stored in values.
Does anyone have an idea of what I am doing wrong?
Thanks!