I would like to display a chart (for a Shiny app), based on data inputted by a user through a file. With the current setup, there is an error message claiming the data is not found, so the plot (from the rCharts package) does not get displayed.
Code attached below:
ui.R
library(rCharts)
library(shinydashboard)
library(shiny)
dashboardPage(
skin = "black",
header <- dashboardHeader(
titleWidth = 475
),
sidebar <- dashboardSidebar(
sidebarMenu(
)
),
body <- dashboardBody(
tabItems(
tabItem("setup",
box(width = 4,title = tags$b('Input Dataset'), solidHeader = T, status = 'primary', collapsible = T,
helpText("Default max. file size is 5 MB. Please upload both files for analysis in csv format."),
fileInput("file1","Upload the first file"),
fileInput("file2","Upload the second file")
),
box(height = 500, width = 12,title = tags$b('Visualize Data'), solidHeader = T, status = 'primary',
showOutput("myPlot", "Highcharts")
)
)
)
)
)
server.R
library(shiny)
library(rCharts)
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
observe({
file1 = input$file1
file2 = input$file2
if (is.null(file1) || is.null(file2)) {
return(NULL)
}
data1 = read.csv(file1$datapath)
data2 = read.csv(file2$datapath)
})
output$myPlot<-renderChart2({
# Prepare data
data1[,2] <- (data1[,2])/sum(data1[,2])
# Create chart
a <- rCharts:::Highcharts$new()
a$chart(type = "column")
a$xAxis(categories = rownames(x))
a$yAxis(title = list(text = "Normalized Intensity"))
a$data(data1)
a$set(width = 600, height = 500)
return(a)
})
})
Try adding something like this. Make sure you check for nrow and return and empty Highcharts$new() object as renderChart2 expects one.
library(shiny)
library(rCharts)
# Define server logic required to draw a histogram
shinyServer(function(input, output) {
data1 <- reactive({read.csv(file1$datapath)})
data2 <- reactive({read.csv(file2$datapath)})
output$myPlot<-renderChart2({
data1 <- data1()
# Prepare data
if(nrow(data1==0)){return(Highcharts$new())}
data1[,2] <- (data1[,2])/sum(data1[,2])
# Create chart
a <- rCharts:::Highcharts$new()
a$chart(type = "column")
a$xAxis(categories = rownames(x))
a$yAxis(title = list(text = "Normalized Intensity"))
a$data(data1)
a$set(width = 600, height = 500)
return(a)
})
})
Related
library(needs)
needs(
shiny,
ggplot2,
tidyverse,
shinydashboard,
DT
)
source("~/functions.R",local = T)
# Define UI for application that draws a histogram
header = dashboardHeader(
# tags$li(class = "dropdown",
# tags$style(".main-header {max-height: 80px}"),
# tags$style(".main-header .logo {height: 80px}")),
#title = tags$img(src='logo.png',height='100',width='200')
)
sidebar = dashboardSidebar(
menuItem("Full data",tabName="Data",icon=icon("table"),startExpanded = F,
fileInput("file","Upload CSV files",multiple=TRUE,accept=("text/comma"))),
menuItem(text = 'Simulate',tabName = 'simulate',icon=icon('chart-line'),
helpText('Simulation Parameters'),
radioButtons('type',"Please choose the type of analysis:",choices = list("Gender" = 1,"US Minority Status" = 2),selected = 1),
sliderInput("numSims","Number of simulations:",min = 1, max = 10000,step = 1000,value = 10000),
sliderInput("numYears","Number of years to simulate:",min = 1,max = 5,value = 3,step = 1),
numericInput('turnover','Total Turnover', value = 10),
sliderInput('promoRate','Set Promo rate', value = 25, min = 1, max = 100, step = 5),
sliderInput('growthRate','Set growth rate',value = 0,min=0,max=100,step = 1),
helpText('0% Growth Rate assumes a flat, constant headcount'),
actionButton('go',label = "Update"),width = 4)
)
body <- dashboardBody(
tabItems(
tabItem(
tabName = 'data',
fluidRow(wellPanel(
fileInput(
inputId = 'file',
label = "File Upload:",
accept = c("csv", ".csv")))),
wellPanel(DT::dataTableOutput('table'))),
tabItem(
tabName = 'simulate',
fluidRow(
wellPanel(
DT:::dataTableOutput('simDataTable')
))
)
))
ui = shinydashboard::dashboardPage(header,sidebar,body,skin='red')
server = server <- function(input, output) {
options(shiny.maxRequestSize = 30 * 1024 ^ 2)
dataset <- reactive({
req(input$file)
read.csv(input$file$datapath)
})
output$table = renderDataTable(dataset(), filter = 'top',options = list(scrollX = TRUE))
simulate = eventReactive(input$go,{
req(input$numSims,input$type)
x = dataset()
temp = dataSim(x,type=input$type,
numSims = input$numSims)
})
simulateAvg = reactive({
x = simulate()
y = x %>% group_by(Role) %>% summarise(mean(freq))
})
output$simDataTable = renderDataTable(simulateAvg())
}
shinyApp(ui,server)
I'm having some trouble with two issues.
1.) The formatting of the shiny dashboard is odd. The text on the side bar seems very compacted and not what other shiny dashboards look like. I'm not sure what the issue is.
2.) After upload, a table is suppose to appear on the dashboard body but it doesn't
3.) Once a table appears and I head to the simulate tab, will the dashboard body change accordingly and display the simulateAvgData set that I populated?
The dataSim function is from the source file on top. I don't receive any errors when I run anything so looking for guidance and inputs to whether or not this shiny dashboard work as intended. I'm newer to the dashboard packages from shiny.
You have a couple of issues here. You do not need a fileInput statement inside dashboardBody. Next, within dashboardSidebar, you can define fileInput at the top level of menuItem (option 1 in the code below), or a sub-level of the first menuItem (option 2 below). In either case, you need to have a menuItem with a tabName where you want to display the file that was read in. Once you read the input file, you need to select the appropriate tab to see the displayed data. Try this code
header <- dashboardHeader()
### option 1: fileInput at the first menuItem level
# sidebar <- dashboardSidebar(width=320,
# menuItem("Full data",tabName="Data",icon=icon("table"),startExpanded = F),
# fileInput("file","Upload CSV files",multiple=FALSE,accept=c("csv", ".csv"))
# )
### option 2 - fileInput as a subitem
sidebar <- dashboardSidebar(width=320,
menuItem("Full data",tabName="noData",icon=icon("table"),startExpanded = F, ## data not displayed for this tabName
menuItem("Full_data",tabName="Data", icon=icon("table")),
fileInput("file","Upload CSV files",multiple=FALSE,accept=c("csv", ".csv")))
)
body <- dashboardBody(
tabItems(
tabItem(
tabName = 'Data',
fluidRow(DTOutput('table')))
))
ui <- shinydashboard::dashboardPage(header,sidebar,body,skin='red')
server <- function(input, output, session) {
data1 <- reactive({
req(input$file)
data <- read.csv(input$file$datapath,sep = ",", header = TRUE)
})
output$table <- renderDT(data1())
}
shinyApp(ui,server)
I want to draw a plot using shiny R when I select items from selectInput .The problem is in the selection of items from select input, I have tried
plot(mydata$input$getCol1,mydata$input$getCol2],type="l",col="blue") but i got another error which tells, need finite 'xlim' values. I also checked the NA there where no Na in my dataset.
My
UI.R code is as follows
library(shiny)
library(shinydashboard)
library(DT)
library(ggplot2)
library(plotly)
ui <- dashboardPage(
dashboardHeader(title="Engagement and Passionate",titleWidth = 350),
# Sidebar ######################################
dashboardSidebar(
width = 150,
sidebarMenu(id = "mysidebar",
menuItem("Engagement",
menuSubItem("Bittorent", tabName =
"subItemOne"),
menuSubItem("Twitter", tabName = "subItemTwo"),
menuSubItem("Tumblr", tabName =
"subItemThree"),
menuSubItem("Youtube", tabName =
"subItemFour"),
menuSubItem("Dailymotion", tabName =
"subItemFive")),
menuItem("Charts",
menuSubItem("AP", tabName = "APC"),
menuSubItem("Anp", tabName = "ANPC"))
)),
# Body #######################################
dashboardBody(
fluidRow(box(width = 3,h2("Upload file"),fileInput("file2", "Choose
CSV File",
accept = NULL)),
box(width=8,h2("Raw Data"),DT::dataTableOutput("pltable")
)
),
tabItems(
tabItem(tabName = "subItemOne",
h2("Bittorent Insight"),
box(title="select the variable",width=3
,uiOutput("getCol1"),uiOutput("getCol2"),status =
"warning",solidheader=TRUE),
plotOutput("graph"))
,
tabItem(tabName = "subItemTwo",
h2("Twitter Insight")
),
tabItem(tabName = "subItemThree",
h2("Tumblr Insight")
),
tabItem(tabName = "subItemFour",
h2("Youtube Insigth")
),
tabItem(tabName = "subItemFive",
h2("Daily motion Insigth")
))))
Server.R
options(shiny.maxRequestSize=30*1024^2)
server <- function(input, output) {
#Function to read table
rawdata <<- reactive({
file1 <- input$file2
if(is.null(file1)){return()}
read.csv(file=file1$datapath,1,stringsAsFactors=FALSE)
})
output$getCol1<-renderUI({
selectInput("Variable1","Choose
Option:",as.list(colnames(rawdata())))
})
output$getCol2<-renderUI({
selectInput("Variable2","Choose
Option:",as.list(colnames(rawdata())))
})
#raw Datatable for platform
output$pltable<-DT::renderDataTable({
if(is.null(rawdata)){return()}
DT::datatable(rawdata(),
extensions="Responsive",options=list(pageLength=3),class='cell-
border strip',selection='single')
})
#access rawdata
output$graph <- renderPlot({
mydata <- as.data.frame(rawdata())
# p <- ggplot(mydata,
aes(mydata$input$getCol1,mydata$input$getCol2,
color=factor(mydata[3]))) + geom_point()
#ggplotly(p)
plot(x=mydata[input$getCol1],
y=mydata[input$getCol2],type="l",col="blue")
#plot(mydata[2])
})
}
The error that I received is as follows:
only one column in the argument to 'pairs'
I also tried the following code
output$graph <- renderPlot({
mydata <- as.data.frame(rawdata())
ggplot(mydata, aes_string(x = input$getCol1, y = input$getCol2))
})
it does not show any line in the graph however it doesnot show any error as well.
Could you please let me know what is this problem.
You need to call id of select input which are Variable1 and Variable2 instead of calling getCol1 and getCol2
Try this :
output$graph <- renderPlot({
df<- rawdata()
plot(df[,input$Variable1],df[,input$Variable2])
})
Or you can try the following code:
ggplot(df, aes_string(input$Variable1,input$Variable2))+geom_point(colour=‘blue’)
I have a shiny application in which I'd like to capture which bar a user clicks on and store that value in a reactive expression to be referenced elsewhere for filtering. The problem is that the reactive expression reruns when I switch tabs and so the value doesn't sync up between the two tabs.
I have a reproducible example below.
When you load the app and click on the Goats bar, the selection at the bottom changes to 'Goats', but if you then change the tab to Bar2 the reactive expression reruns and therefore returns Giraffes again. So I end up with two separate values for the reactive expression across the different tabs. If I choose Goats on the first tab, I want it to remain when I switch to Bar2 tab and only update when I make another click.
Note that I realize I can resolve this in this example by removing the source argument from the event_data function, but in my application I have other charts which I do not want the user to be able to click on so I need to set the source to only these charts.
library(shiny)
library(plotly)
library(ggplot2)
library(shinydashboard)
df_test <- data.frame(c("Giraffes","Goats"),c(1,4))
df_test <- setNames(df_test,c("species","amount"))
ui <- dashboardPage(
dashboardHeader(title = "Click Example",
titleWidth = 300),
dashboardSidebar(
width = 300,
sidebarMenu(
menuItem("Tab", tabName = "tab")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "tab",
fluidRow(
column(12, tabBox(
title = "",
id = "tabSet",
width = 12,
height = 500,
tabPanel("Bar1", plotlyOutput(outputId="bar_one")),
tabPanel("Bar2", plotlyOutput(outputId="bar_two"))
)
),
column(12,textOutput(outputId = "selection")))
)
)
)
)
server <- function(input, output, session) {
click_reactive = reactive({
d <- event_data("plotly_click",source=input$tabSet)
if (length(d) == 0) {species = as.vector(df_test$species[1])}
else {species = as.character(d[4])}
return(species)
})
output$bar_one <- renderPlotly({
p <- plot_ly(data = df_test, x = ~amount, y = ~species, type = 'bar', orientation = 'h', source = "Bar1")
})
output$bar_two <- renderPlotly({
p <- plot_ly(data = df_test, x = ~amount, y = ~species, type = 'bar', orientation = 'h', source = "Bar2")
})
output$selection <- renderText({
species <- click_reactive()
return(species)
})
}
shinyApp(ui, server)
You need to change the source to be under one name:
library(shiny)
library(plotly)
library(ggplot2)
library(shinydashboard)
df_test <- data.frame(c("Giraffes","Goats"),c(1,4))
df_test <- setNames(df_test,c("species","amount"))
ui <- dashboardPage(
dashboardHeader(title = "Click Example",
titleWidth = 300),
dashboardSidebar(
width = 300,
sidebarMenu(
menuItem("Tab", tabName = "tab")
)
),
dashboardBody(
tabItems(
tabItem(tabName = "tab",
fluidRow(
column(12, tabBox(
title = "",
id = "tabSet",
width = 12,
height = 500,
tabPanel("Bar1", plotlyOutput(outputId="bar_one")),
tabPanel("Bar2", plotlyOutput(outputId="bar_two"))
)
),
column(12,textOutput(outputId = "selection")))
)
)
)
)
server <- function(input, output, session) {
v <- reactiveValues()
observe({
d <- event_data("plotly_click",source="Bar1")
if (length(d) == 0) {species = as.vector(df_test$species[1])}
else {species = as.character(d[4])}
v$click <- species
})
output$bar_one <- renderPlotly({
p <- plot_ly(data = df_test, x = ~amount, y = ~species, type = 'bar', orientation = 'h', source = "Bar1")
})
output$bar_two <- renderPlotly({
p <- plot_ly(data = df_test, x = ~amount, y = ~species, type = 'bar', orientation = 'h', source = "Bar1")
})
output$selection <- renderText({
v$click
})
}
shinyApp(ui, server)
If you run the R shiny script below, we get two boxes in a dashboard, the left box has a bar chart and right has a DT table, when I click on any bar of the chart using event_data("plotly_click"), I want the corresponding Employee to be displayed in the table besides, like when clicked on first bar, "r1" should be displayed in the table besides. I tried doing "user_cases$base1[d[3]]" but it throws an error as "Error: invalid subscript type 'list'". I will attach the snapshot for the reference, please help me with the same.
## app.R ##
library(shiny)
library(shinydashboard)
library(ggplot2)
library(plotly)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Sankey Chart"),
dashboardSidebar(
width = 0
),
dashboardBody(
box(title = "Sankey Chart", status = "primary",height = "455" ,solidHeader =
T,
plotlyOutput("sankey_plot")),
box( title = "Case Summary", status = "primary", height = "455",solidHeader
= T,
dataTableOutput("sankey_table"))
)
)
server <- function(input, output)
{
output$sankey_plot <- renderPlotly({
height2 = c(56,45,23,19,8)
base1 = c("r1","r4","r2","r5","r3")
user_cases = data.frame(base1,height2)
pp1 <<- ggplot(user_cases, aes(x = reorder(base1,-height2), y = height2)) +
geom_bar(stat = "identity", fill = "#3399ff" ) + scale_y_discrete(name
="Cases") + scale_x_discrete(name = "Employee")
ggplotly(pp1, tooltip="text",height = 392)
})
output$sankey_table <- renderDataTable({
d <- event_data("plotly_click")
user_cases$base1[d[3]]
})
}
shinyApp(ui, server)
Dataset to be fetched
I am trying to fetch subset of the data from the patients dataset from bupaR library. The code for doing it is as follows:
patients_final <- patients[patients$employee == as.data.frame(
user_time$employee[as.numeric(d[3])])]
but the error I get is: "Can't use matrix or array for column indexing" attaching the snapshot for the help.
Have a look at the modified code, I have changed user_cases$base1[d[3]] to as.data.frame(user_cases$base1[as.numeric(d[3])])
## app.R ##
library(shiny)
library(shinydashboard)
library(ggplot2)
library(plotly)
library(DT)
height2 = c(56,45,23,19,8)
base1 = c("r1","r4","r2","r5","r3")
user_cases = data.frame(base1,height2)
ui <- dashboardPage(
dashboardHeader(title = "Sankey Chart"),
dashboardSidebar(
width = 0
),
dashboardBody(
box(title = "Sankey Chart", status = "primary",height = "455" ,solidHeader =
T,
plotlyOutput("sankey_plot")),
box( title = "Case Summary", status = "primary", height = "455",solidHeader
= T,
dataTableOutput("sankey_table"))
)
)
server <- function(input, output)
{
output$sankey_plot <- renderPlotly({
pp1 <<- ggplot(user_cases, aes(x = reorder(base1,-height2), y = height2)) +
geom_bar(stat = "identity", fill = "#3399ff" ) + scale_y_discrete(name
="Cases") + scale_x_discrete(name = "Employee")
ggplotly(pp1, tooltip="text",height = 392)
})
output$sankey_table <- renderDataTable({
d <- event_data("plotly_click")
as.data.frame( user_cases$base1[as.numeric(d[3])])
})
}
shinyApp(ui, server)
The output is as below:
You can modify the dataframe output as per your requirement.
Hope it helps!
I'm using Dygraphs package for visualizing actual and the time series predicted values in R shiny. Here is the sample code that I used to generate the Dygraph. In some cases where the data points are less Holt Winters(gamma =T) does not give any prediction and I need to show an empty Dygraph with the title "Insufficient Data"). I'm not able to do this. Appreciate any help on this
library(dygraphs)
plotDyg <- fluidPage(
fluidRow(
box(selectizeInput("c1", "Enter a key",
choices = reactive({sort(unique(df$key))})(),
multiple = FALSE),width=3),
box(dygraphOutput("tsDy"), width = 10, height = 500))
)
ui <- dashboardPage(
dashboardHeader(title = "XYZ"),
dashboardSidebar(
sidebarMenu(
menuItem("abc", tabName = "sidebar2", icon = icon("bar-chart") ,
menuSubItem("def",icon = icon("folder-open"), tabName = "subMenu1")
)
)
),
dashboardBody(
tabItems(
tabItem(tabName = "subMenu1",
fluidRow(
tabBox(
title = "ghi", id = "tabset2",height = "1500px",width = 100,
tabPanel("abcdef", plotDyg)
)
)
)
)
)
)
server <- function(input, output) {
output$tsDy <- renderDygraph({
if(!is.null(input$c1)){
df.0 <- reactive({df[df$key == input$c1,]})()
tspred <- reactive({
df.0 <- convert_to_ts(df.0) # converts column "fin_var" to a monthly time series and returns the entire dataframe
act <- df.0$fin_var
hw <- tryCatch(HoltWinters(df.0$fin_var), error=function(e)NA)
if(length(hw) > 1){
p <- predict(hw, n.ahead = 12, prediction.interval = TRUE, level = 0.95)
all1 <- cbind(act, p)
}else{all1 <- matrix()}
})
if(!is.na(tspred())){
dygraph(tspred(), main = "TS Predictions") %>%
dySeries("act", label = "Actual") %>%
dySeries(c("p.lwr", "p.fit", "p.upr"), label = "Predicted") %>%
dyOptions(drawGrid = F) %>%
dyRangeSelector()
}else{dygraph(matrix(0), main = "Insufficient Data")} # I could just do 'return()' but I want to show an empty Dygraph with the title
}else{return()}
})
}
I too am unable to render Dygraphs with an empty time series. To render a message to the user I used the validate/need functions in Shiny
In your case I would replace
if(!is.na(tspred())){
With
validate(need(!is.na(tspred())), "Insufficient Data"))
This will avoid the "error: argument is of length zero" message within Dygraphs and print an appropriate message to the end user.