use reactive dataset in shiny R and draw a plot - r

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’)

Related

Shiny Dashboard formatting issue

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)

How to persist event_data across tabs in Shiny?

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)

Placing ifelse statements into a render expression Shiny

In the below code, I am attempting to create an input to show all of my markets, or just a selection within a plot and a data table. I am doing this through, or attempting, through ifelse statements within my render functions, however I am getting errors, and neither the plot or data table will render. They do render without the if else statements. I have included an Example data set to hopefully help place in context.
ui <- dashboardPage(
dashboardHeader(title = "Example"),
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard", tabName = "Dashboard"),
menuItem("Example", tabName = "example"))),
dashboardBody(
tabItems(
tabItem(tabName = "Dashboard",
fluidRow(
valueBoxOutput("example"))),
tabItem(tabName = "example",
fluidRow(
box(title = "Example",
plotOutput("plotexample"), width = 12),
box(title = "Data Selection",
selectInput("market","Market(s): ", c(unique(data$marketnum),"All"),multiple = T, selectize = T, selected = "All"))),
fluidRow(
box(DT::dataTableOutput("markettable"), width = 12))))))
server <- function(input,output) {
ExampleAllMarkets <- reactive({
ExampleData %>%
group_by(Event,marketnum) %>%
summarise(ItemCount = n_distinct(ItemNumber))
})
Example <- reactive({
ExampleData %>%
filter(marketnum == input$market) %>%
group_by(Event,marketnum) %>%
summarise(PolicyCount = n_distinct(Policy_Number_9_Digit))
})
output$example <- renderValueBox({
valueBox(
paste0("44", "%"), "example", icon = icon("car"),
color = "red"
)
})
I am placing ifelse statements within my render blocks reactive to whether or not "All" is selected.
output$plotexample <- renderPlot({
ifelse(input$market=="All",
ggplot(Example(), aes(x=MBC_Number, y=ItemCount)) +
geom_bar(stat="identity"),
ggplot(ExampleAllMarkets(), aes(x=marketnum, y=ItemCount))
+
geom_bar(stat="identity"))
})
output$markettable <- DT::renderDataTable({
ifelse(input$market == "All",
ExampleAllMarkets(),
Example())
})
}
shinyApp(ui,server)
Example Data in csv format
marketnum,ItemNumber
2,118
7,101
1,109
2,109
10,101
4,102
8,100
12,103
5,106
13,116
5,112
10,103
7,113
9,114
10,112
6,114
2,116
11,113
3,107
13,102
8,107
10,109
12,110
1,120
4,106
8,116
2,112
2,106
11,101
6,108
11,107
10,111
6,120
10,118
11,119
13,117
You probably cannot use ifelse in this scenario.
Analyzing the source code for ifelse, since a plot object is not so simple, it does not just return the plot itself, but
rep(plot, length.out = 1)
or equivalently plot[1] which is just the dataset of the plot. A plot object has a length > 1 and for those, ifelse only returns its first element.
This can be easily confirmed by evaluating
> ifelse(T, c(1, 2), c(3, 4))
[1] 1
So the render function cannot draw anything, since it's input is just this dataset.
You will simply have to use the regular if else.

Produce a graph from an editable table in Shiny

I have a shiny application with the following ui:
library(rhandsontable)
library(shiny)
library(ggplot2)
ui = fluidPage(
# App title ----
titlePanel("Tabsets"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Tabset w/ plot, summary, and table ----
tabsetPanel(type = "tabs",
tabPanel("Summary", rHandsontableOutput('contents'),
actionButton("saveBtn", "Save changes")
),
tabPanel("Tab",
rHandsontableOutput('contentFinal')),
tabPanel("Dashboard",
plotOutput('dashboard1'))
)
)
)
)
And the following server
library(dplyr)
library(rhandsontable)
options(shiny.maxRequestSize = 9*1024^2)
server = function(input, output) {
values <- reactiveValues()
Post <- c("", "")
list2 <- c(12,13)
df <- data.frame(Post, list2)
output$contents <- renderRHandsontable({
rhandsontable(df, width = 550, height = 300) %>%
hot_col(col = "Post", type = "dropdown")
})
saveData <- eventReactive({input$saveBtn},{
finalDF <- hot_to_r(input$contents)
finalDF$Post <- ifelse(finalDF$Post =="",NA,finalDF$Post)
newDF <- finalDF[complete.cases(finalDF),]
return(newDF)
})
output$contentFinal <- renderRHandsontable(
rhandsontable(saveData())
)
output$dashboard1 <- renderPlot(
ggplot(input$contentFinal, aes(x = Post, y = list2 )) +
geom_bar(stat = "identity")
)
observeEvent(input$saveBtn, saveData())
}
shinyApp(ui = ui, server = server)
The flow is like this:
In the first tab, I bring up data with an empty post column
In this tab, I can add a name for the post and save it.
As soon as I save he rows with values for post become visible in the next tab.
Then the next thing I want to do is to have a visual in the dashboard tab that shows the data. Therefore I create:
output$dashboard1 <- renderPlot(
ggplot(input$contentFinal, aes(x = Post, y = List2 )) +
geom_bar(stat = "identity")
)
This however gives me the following ggplot2 errror:
ggplot2 doesn't know how to deal with data of class list
Any thoughts on what goes wrong here?
The problem is because input$contentFinal is handsontable data. We need to convert it to R object using hot_to_r function.
The ggplot should be plotted using the following:
ggplot(hot_to_r(input$contentFinal), aes(x = Post, y = list2 )) +
geom_bar(stat = "identity")
Hope it helps!

Display R Shiny Plot After Inputting File

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)
})
})

Resources