The user selects first a value. Based on it, a rhandsontable appears with multiple, empty columns, with dropdown options - except for the last column, Type_action. This column, which is readOnly should be automatically updated based on values in columns Y and Z as follows: if the value in column Y is less than the value in column Z, Type_action should take value "Upgrade", otherwise, value "Downgrade".
Below my attempt, which fails to produce any value for the Type_action column:
library(shiny)
library(rhandsontable)
library(dplyr)
library(shinydashboard)
ui <- fluidPage( fluidRow(column(6, uiOutput("selA"))),
fluidRow(column(6, rHandsontableOutput('tbl1'))
)
)
server <- function(input, output, session){
dt0 <- data.frame( A = c("S2","S2","S2","S4","S4","S4"),
B = c("1","2","3","1","2","3"),
C = c(10,20,30,40,15,25),
D = c("A","B","C","D","E","F"))
# get the data for the selected BA
dt <- reactive(subset(dt0, A %in% input$selA))
# Render selectInput selBA
output$selA <- renderUI({
ba <- as.vector( unique(dt0$A) )
selectInput("selA","Choose BA", choices = ba)
})
DF <- data.frame("X" = c(""),
"Y" = c(""),
"Z" = c(""),
"Type_action" = c(""))
values <- reactiveValues(data = DF)
Y <- reactiveVal()
Z <- reactiveVal()
observe({
if(!is.null(input$tbl1)){
values$data <- as.data.frame(hot_to_r(req(input$tbl1)))
}
})
observeEvent(input$tbl1,{
Y(hot_to_r(input$tbl1)$Y)},
ignoreInit= TRUE
)
observeEvent(input$tbl1,{
Z(hot_to_r(input$tbl1)$Z)},
ignoreInit= TRUE
)
output$tbl1 = renderRHandsontable({
req(input$selA)
tmpTable <- rhandsontable(values$data, rowHeaders = FALSE, selectCallback = TRUE, width =
1000, height = 500) %>%
hot_table(highlightCol = TRUE, highlightRow = TRUE, stretchH = "all") %>%
hot_col(col = "X", type = "dropdown", colWidths = 90, source =
sort(unique(dt()$B))) %>%
hot_col(col = "Y", type = "dropdown", colWidths = 65, source =
sort(unique(dt()$D))) %>%
hot_col(col = "Z", type = "dropdown", colWidths = 60,source =
sort(unique(dt()$D))) %>%
hot_col(col = "Type_action", colWidths = 50, readOnly = TRUE, type = "text")
if(!is.null(input$tbl1_select$select$r) && !is.na(values$data$Y[input$tbl1_select$select$r])
&& !is.na(values$data$Z[input$tbl1_select$select$r])){
tmpTable <- hot_col(tmpTable,col = "Type_action", type = "text", colWidths = 60,
source = ifelse(as.numeric(factor(Y())) < as.numeric(factor(Z())),"u","d"))
}
tmpTable
})
}
shinyApp(ui, server)
The source argument of hot_col takes
a vector of choices for select, dropdown and autocomplete column types
it's not implemented to modify the content of a text cell (as you tried in the code above).
We can modify a text column by changing the underlying (reactive) data.frame.
Please check the following:
library(shiny)
library(rhandsontable)
library(dplyr)
library(shinydashboard)
ui <- fluidPage( fluidRow(column(6, uiOutput("selA"))),
fluidRow(column(6, rHandsontableOutput('tbl1'))
)
)
server <- function(input, output, session){
dt0 <- data.frame( A = c("S2","S2","S2","S4","S4","S4"),
B = c("1","2","3","1","2","3"),
C = c(10,20,30,40,15,25),
D = c("A","B","C","D","E","F"))
# get the data for the selected BA
dt <- reactive(subset(dt0, A %in% input$selA))
# Render selectInput selBA
output$selA <- renderUI({
ba <- as.vector( unique(dt0$A) )
selectInput("selA","Choose BA", choices = ba)
})
DF <- data.frame("X" = c(""),
"Y" = c(""),
"Z" = c(""),
"Type_action" = c(""))
values <- reactiveValues(data = DF)
Y <- reactiveVal()
Z <- reactiveVal()
observe({
if(!is.null(input$tbl1)){
values$data <- as.data.frame(hot_to_r(req(input$tbl1)))
}
})
observeEvent(input$tbl1,{
Y(hot_to_r(input$tbl1)$Y)},
ignoreInit= TRUE
)
observeEvent(input$tbl1,{
Z(hot_to_r(input$tbl1)$Z)},
ignoreInit= TRUE
)
output$tbl1 = renderRHandsontable({
req(input$selA)
tmpTable <- rhandsontable(values$data, rowHeaders = FALSE, selectCallback = TRUE, width =
1000, height = 500) %>%
hot_table(highlightCol = TRUE, highlightRow = TRUE, stretchH = "all") %>%
hot_col(col = "X", type = "dropdown", colWidths = 90, source =
sort(unique(dt()$B))) %>%
hot_col(col = "Y", type = "dropdown", colWidths = 65, source =
sort(unique(dt()$D))) %>%
hot_col(col = "Z", type = "dropdown", colWidths = 60,source =
sort(unique(dt()$D))) %>%
hot_col(col = "Type_action", colWidths = 50, readOnly = TRUE, type = "text")
if(!is.null(input$tbl1_select$select$r) && !is.na(values$data$Y[input$tbl1_select$select$r])
&& !is.na(values$data$Z[input$tbl1_select$select$r])){
values$data$Type_action <- ifelse(match(Y(), LETTERS) < match(Z(), LETTERS),"Upgrade","Downgrade")
}
tmpTable
})
}
shinyApp(ui, server)
Related
I am developing a Shiny App, where the user can upload data, do some manipulations & create new df from selected rows. I have got till where I can add actionButtons per row in DT but cant make selections work. Selections work as expected if actionButtons are not included in the DT rows. What am I looking for?
1. To be able to toggle between two colors on click within each of the DT row (Orange = not selected; Green = selected, when clicked)
2. Create new data frame from selected rows of the datatable on another actionButton click (Ex: Category 01 or Category 02).
Once any of the Category 01 or Category 02 actionButton is clicked. I get this error Error: incorrect number of dimensions. As shown at the bottom of Image 2.
I have added reproducible code below.
Any help is much appreciated
As in screenshot1, actionbuttons are Orange And in screenshot2 they are Green ,
Data
data <- data.frame(Name = rep(paste("RIS", 1:20, sep = "_")),
Gender = rep(c("Male", "Female"), each = 10),
CDC = rnorm(20),
FDC = rnorm(20),
RDC = rnorm(20),
LDC = rnorm(20)
)
Example Code
library(shiny)
library(DT)
ui <- fluidPage(
titlePanel("simpleApp"),
sidebarLayout(
sidebarPanel(fileInput("file1", "Upload Input file", accept = ".csv"), width = 2,
actionButton("calc", "Calculate"),
hr(style = "border-color: red; height: 5px"),
actionButton("gen1", "Category 01"),
actionButton("gen2", "Category 02")),
mainPanel (
dataTableOutput("table"),
dataTableOutput("table2"),
dataTableOutput("select_table1"),
dataTableOutput("select_table2"))))
server <- function(input, output, session) {
addButtonColumn <- function(df, id, ...) {
f <- function(i) {
as.character(
actionButton(paste(id, i, sep = "_"), class = "btn-warning btn-sm", label = tags$strong("Select"),
onclick = 'Shiny.setInputValue(\"addPressed\", this.id, {priority: "event"})'))
}
addCol <- unlist(lapply(seq_len(nrow(df)), f))
DT::datatable(cbind(Decision = addCol, df),
escape = FALSE, filter = "top", options = list(columnDefs = list(list(targets = 1, sortable = FALSE))))
}
data <- reactive({
df <- input$file1
if(is.null(df))
return(NULL)
df <- read.csv(df$datapath, header = TRUE, sep = ",", row.names = NULL)
return(df)
})
output$table <- DT::renderDataTable(data(), options = list(paging = t, pageLength = 6))
table2 <- eventReactive(input$calc, {
df2 <- input$file1
if(is.null(df2))
return(NULL)
table2 <- data() %>%
mutate("Selection" = CDC * RDC + FDC * LDC) %>%
mutate(across(where(is.numeric), round, 3)) %>%
addButtonColumn("Button")
})
output$table2 <- DT::renderDataTable(table2(), options = list(paging = t, pageLength = 6))
select_table1 <- eventReactive(input$gen1, {
if(is.null(table2)){
return(NULL)
} else {
select_table1 <- table2()[input$table2_rows_selected,]
}
})
select_table2 <- eventReactive(input$gen2, {
if(is.null(table2)){
return(NULL)
} else {
select_table2 <- table2()[input$table2_rows_selected,]
}
})
output$select_table1 <- DT::renderDataTable(select_table1(), options = list(paging = t, pageLength = 6))
output$select_table2 <- DT::renderDataTable(select_table2(), options = list(paging = t, pageLength = 6))
}
shinyApp(ui = ui, server = server)
Some simple CSS can do it.
You called DT::datatable too early in the eventReactive. You need to call it within renderDataTable, otherwise, the render function can't recognize it properly (it can, but table2_rows_selected will not work).
df <- data.frame(Name = rep(paste("RIS", 1:20, sep = "_")),
Gender = rep(c("Male", "Female"), each = 10),
CDC = rnorm(20),
FDC = rnorm(20),
RDC = rnorm(20),
LDC = rnorm(20)
)
library(shiny)
library(DT)
ui <- fluidPage(
titlePanel("simpleApp"),
sidebarLayout(
sidebarPanel(fileInput("file1", "Upload Input file", accept = ".csv"), width = 2,
actionButton("calc", "Calculate"),
hr(style = "border-color: red; height: 5px"),
actionButton("gen1", "Category 01"),
actionButton("gen2", "Category 02")),
mainPanel (
dataTableOutput("table"),
dataTableOutput("table2"),
dataTableOutput("select_table1"),
dataTableOutput("select_table2"))),
tags$style(
'
table.dataTable tr.selected button {
background-color: green;
border-color: green;
}
'
)
)
server <- function(input, output, session) {
addButtonColumn <- function(df, id, ...) {
f <- function(i) {
as.character(
actionButton(paste(id, i, sep = "_"), class = "btn-warning btn-sm", label = tags$strong("Select"),
onclick = 'Shiny.setInputValue(\"addPressed\", this.id, {priority: "event"})'))
}
addCol <- unlist(lapply(seq_len(nrow(df)), f))
cbind(Decision = addCol, df)
}
data <- reactive({
df
})
output$table <- DT::renderDataTable(data(), options = list(paging = t, pageLength = 6))
table2 <- eventReactive(input$calc, {
df2 <- df
if(is.null(df2))
return(NULL)
data() %>%
mutate("Selection" = CDC * RDC + FDC * LDC) %>%
mutate(across(where(is.numeric), round, 3)) %>%
addButtonColumn("Button")
})
output$table2 <- DT::renderDataTable(DT::datatable(
table2(), escape = FALSE, filter = "top",
options = list(columnDefs = list(list(targets = 1, sortable = FALSE, paging = t, pageLength = 6)))
))
select_table1 <- eventReactive(input$gen1, {
if(is.null(table2)){
return(NULL)
} else {
print(input$table2_rows_selected)
select_table1 <- table2()[input$table2_rows_selected,]
}
})
select_table2 <- eventReactive(input$gen2, {
if(is.null(table2)){
return(NULL)
} else {
select_table2 <- table2()[input$table2_rows_selected,]
}
})
output$select_table1 <- DT::renderDataTable(DT::datatable(select_table1(), escape = FALSE, options = list(paging = t, pageLength = 6)))
output$select_table2 <- DT::renderDataTable(select_table2(), escape = FALSE, options = list(paging = t, pageLength = 6))
}
shinyApp(ui = ui, server = server)
Disabled your uploading part. You need to change it back.
I tried to publish an R Shiny app but I got this error 1
I don't know what to do
ps: I have updated all the libraries that I use inside the code but still nothing I get the same error
would you please help me!
I am using the following code:
library(shiny)
library(dplyr)
library(rgdal)
library(leaflet)
library(shinyWidgets)
library(shinydashboard)
basin <- readOGR("data/basin.kml", "basin")
map_allocator1 <- read.csv('data/map_allocator1.csv')
map_allocator2 <- read.csv('data/map_allocator2.csv')
map_allocator3 <- read.csv('data/map_allocator3.csv')
tour_polyline <- readOGR("data/tour1.kml", "tour1")
info_360<- read.csv('data/360_photos.csv')
ui <-
fluidPage(theme = "mystyle.css",
sidebarLayout(
sidebarPanel(
tags$head(
tags$style(HTML(".main-sidebar {background-color: #D6E3F0!important;}")))
,
sliderTextInput(
inputId = "mySliderText",
label = "Story line",
grid = TRUE,
force_edges = TRUE,
choices = c('1','2','3','4','5','6')
)
,br(),br()
,
(leafletOutput("story_map")),
htmlOutput("frame2")
),
mainPanel(
tags$head(tags$style("#current_info{
margin-left:20px;
margin-right:10px;
}"
)
)
,
valueBoxOutput("story_line_valubox"),
htmlOutput("frame")
,
div(id='box1', "Infromation about the current location")
,
htmlOutput("frame1")
#uiOutput("current_info")
)
)
)
server <- function(input, output) {
printmap <- reactive({
if (input$mySliderText %in% info_360$press )
{
info_360 %>%
filter(press == input$mySliderText)
}
})
printingvaluebox <- reactive({
if (input$mySliderText %in% info_360$press )
{
info_360 %>%
filter(press == input$mySliderText) %>%
pull(valuebox)
}
})
output$story_map<- renderLeaflet({
leaflet() %>%
addProviderTiles("Stamen.Watercolor",options = providerTileOptions(minZoom=6, maxZoom=6)) %>%
addPolygons(data = basin,color = "black",weight = 2,opacity = 1,fillOpacity = 0.05 )%>%
addCircleMarkers(data = map_allocator1,
lat = ~lat, lng = ~lon,
label = ~no,
radius = 8, fillOpacity = 3/4, stroke = FALSE, color = 'steelblue',
labelOptions = labelOptions(noHide = TRUE, offset=c(0,0), textOnly = TRUE)
)%>%
addCircleMarkers(data = map_allocator2,
lat = ~lat, lng = ~lon,
label = ~no,
radius = 8, fillOpacity = 3/4, stroke = FALSE, color = 'red',
labelOptions = labelOptions(noHide = TRUE, offset=c(0,0), textOnly = TRUE)
)%>%
addCircleMarkers(data = map_allocator3,
lat = ~lat, lng = ~lon,
label = ~no,
radius = 8, fillOpacity = 3/4, stroke = FALSE, color = 'yellow',
labelOptions = labelOptions(noHide = TRUE, offset=c(0,0), textOnly = TRUE)
)%>%
addPolylines(data=tour_polyline, color = "red",weight = 1,opacity = 1)%>%
addMarkers(data=printmap())
})
output$story_line_valubox <- renderValueBox({
valueBox(
printingvaluebox(),
width = 7,
"Current Excursion Station",
color = "blue"
)
})
output$story_line_map<- renderLeaflet({
leaflet() %>%
addProviderTiles("Esri.WorldImagery",options = tileOptions(minZoom = 3 , maxZoom = 16)) %>%
setView(lng=printmap()$lon, lat=printmap()$lat, zoom=printmap()$zoom_level)
})
selectHtml <- reactive({
if (input$mySliderText ==1)
{
return(("trial1.html"))
}
else
{
return(("triaL2.html"))
}
})
frame_link<- reactive({
if (input$mySliderText %in% info_360$press )
{
info_360 %>%
filter(press == input$mySliderText) %>%
pull(mapox)
}
})
output$frame <- renderUI({
tags$iframe(src=frame_link(), height=700, width=1000)
})
output$frame1 <- renderUI({
tags$iframe(src=selectHtml(), height=700, width=1000)
})
output$frame2 <- renderUI({
tags$iframe(src='carousel.html', height=390, width=575, style="position:relative; top: 20px; left: 0px;")
})
}
# Run the application
shinyApp(ui = ui, server = server)
I have published 3 apps in R Shiny and all of them were successfully completed, this time I don't know what is the exact problem!
I am trying to reproduce the decomposed time series plot with highchart.
The result is perfect in the working directory of r but when I put it in r shiny no result comes out.
Here is my code
library(shinyjs)
library(shiny)
library(shinydashboard)
library(highcharter)
library(forecast)
shinyOptions(bslib = TRUE)
bs_global_theme()
bs_theme_base_colors(bg = "#002B36", fg = "#EEE8D5")
bs_theme_accent_colors(primary = "#2AA198")
thematic::thematic_shiny()
ui<-fluidPage(
theme=shinytheme("cerulean"),
themeSelector(),
useShinyjs(),
navbarPage(
title= "Stock exchange", position = "static-top",
id="nav",
tabPanel("Single stock analysis",value = "single_stock", icon = icon("chart-area"),
sidebarLayout(
div(id = "Sidebar",
sidebarPanel(width = 3, align = "center",
selectInput("ticker",
strong("Ticker"),
# quotes$Symbole,
choices = c("AirPassengers", "ttrc"),
selectize = TRUE
),
dateRangeInput("date", strong("Select data range"),
start = "2012-01-01", end = (Sys.Date()-1)
),
tags$br(),
fluidPage(column(width = 3, "Session")
)
)),
mainPanel(
fluidRow(align = "center",
selectInput("hideorshow", label = strong("Sidebar disposition"),
choices = c("Show", "Hide"), selected = "Show")),
tabsetPanel(
tabPanel("Data structure and summary",
icon = icon("table"),
h1(align = "center",
strong(" STRUCTURE OF THE DATAFRAME ")),
tags$br(),tags$b(),class="fa fa-table",
verbatimTextOutput("struc"),
tags$br(),tags$br(),
h1(align = "center",strong(" SUMMARY OF THE DATAFRAME ")),
br(),verbatimTextOutput("summary1")
),
tabPanel("Dataset",icon = icon("tablet-alt"), DTOutput('tbl1')),
tabPanel("Plot",icon = shiny::icon('chart-bar'), br(),br(), br(),
airDatepickerInput(inputId = "date.ts",
strong("Time of the first observation"),
value = "2017-01-01",
minDate = "1998-09-16",
maxDate = Sys.Date(),
view = "months",
minView = "months",
dateFormat = "yyyy-mm"),
highchartOutput("closing_pr.ts",width = "auto", height = "600px"),
),
)
)
)),
tabPanel("Multiple stocks analysis", tabName = "mult_stock", icon = icon("th"))
)
)
I think the problem is hide in the server; exactely the renderHighchart but i can't find it. Please any help will be appreciate.
cs <- new.env()
dt_new <- eventReactive(c(input$ticker,input$date[1],input$date[2]), {
if (input$ticker =="AirPassengers"){
data(AirPassengers)
mydata1 <- AirPassengers
}
else if (input$ticker =="ttrc"){
data(ttrc)
mydata1 <- ttrc
}
mydata1
})
output$closing_pr.ts<-renderHighchart({
year.ts <- as.numeric(year(input$date.ts))
month.ts <- as.numeric(month(input$date.ts))
dc <- decompose(AirPassengers)
df <- as.data.frame(dc[c("x","trend","seasonal","random")])
df2 <- data.frame(Date = index(dc$x),
apply(df, 2, as.numeric))
names(df2) <- c("Date", "Observed", "Trend", "Seasonal", "Random")
df2$Date <- as.Date(yearmon(df2$Date))
df2 <- as.xts(df2[,-c(1)],
order.by = df2$Date)
df2 <- round(df2, digits = 3)
highchart(type = "stock") %>%
hc_title(text = "TIME SERIE DECOMPOSITION") %>%
hc_add_series(df2[, "Observed"], yAxis = 0, name = "Observed", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 1L, title = list(text = "Observed"), relative = 2) %>%
hc_add_series(df2[, "Trend"], yAxis = 1, type = "line",name = "Trend", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 2L, title = list(text = "Trend"), relative = 1)%>%
hc_add_series(df2[, "Seasonal"], yAxis = 2, type = "line",name = "Seasonal", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 1L, title = list(text = "Seasonal"), relative = 2) %>%
hc_add_series(df2[, "Random"], yAxis = 3, type = "line", name = "Random", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 2L, title = list(text = "Random"), relative = 1)%>%
hc_exporting(
enabled = TRUE, # always enabled,
filename = paste0("Closing price decomposition line charts from ",
min(index(df2)),
" to ", max(index(df2))))%>%
hc_colors(colors = c("blue", "red", "cyan", "darkgreen"))
})
observeEvent(input$hideorshow, {
if ( input$hideorshow== "Show") {
shinyjs::show(id = "Sidebar")}
else {shinyjs::hide(id = "Sidebar")}
})
output$summary1 <- renderPrint({
summary(dt_new())
})
output$struc<- renderPrint({
str(dt_new())
})
}
shinyApp(ui=ui, server = server)
Try this
library(shinyjs)
library(shiny)
library(shinydashboard)
library(highcharter)
library(forecast)
library(lubridate)
library(zoo)
library(xts)
shinyOptions(bslib = TRUE)
# bs_global_theme()
# bs_theme_base_colors(bg = "#002B36", fg = "#EEE8D5")
# bs_theme_accent_colors(primary = "#2AA198")
# thematic::thematic_shiny()
ui<-fluidPage(
#theme=shinytheme("cerulean"),
#themeSelector(),
useShinyjs(),
navbarPage(
title= "Stock exchange", position = "static-top",
id="nav",
tabPanel("Single stock analysis",value = "single_stock", icon = icon("chart-area"),
sidebarLayout(
div(id = "Sidebar",
sidebarPanel(width = 3, align = "center",
selectInput("ticker",
strong("Ticker"),
# quotes$Symbole,
choices = c("AirPassengers", "ttrc"),
selectize = TRUE
),
dateRangeInput("date", strong("Select data range"),
start = "2012-01-01", end = (Sys.Date()-1)
),
tags$br(),
fluidPage(column(width = 3, "Session")
)
)),
mainPanel(
fluidRow(align = "center",
selectInput("hideorshow", label = strong("Sidebar disposition"),
choices = c("Show", "Hide"), selected = "Show")),
tabsetPanel(
tabPanel("Data structure and summary",
icon = icon("table"),
h1(align = "center",
strong(" STRUCTURE OF THE DATAFRAME ")),
tags$br(),tags$b(),class="fa fa-table",
verbatimTextOutput("struc"),
tags$br(),tags$br(),
h1(align = "center",strong(" SUMMARY OF THE DATAFRAME ")),
br(),verbatimTextOutput("summary1")
),
tabPanel("Dataset",icon = icon("tablet-alt"), DTOutput('tbl1')),
tabPanel("Plot",icon = shiny::icon('chart-bar'), br(),br(), br(),
airDatepickerInput(inputId = "date.ts",
strong("Time of the first observation"),
value = "2017-01-01",
minDate = "1998-09-16",
maxDate = Sys.Date(),
view = "months",
minView = "months",
dateFormat = "yyyy-mm"),
highchartOutput("closing_prts",width = "auto", height = "600px"),
),
)
)
)),
tabPanel("Multiple stocks analysis", tabName = "mult_stock", icon = icon("th"))
)
)
server <- function(input, output, session){
cs <- new.env()
# dt_new <- eventReactive(c(input$ticker,input$date[1],input$date[2]), {
dt_new <- reactive({
if (input$ticker =="AirPassengers"){
data(AirPassengers)
print("Hello")
mydata1 <- AirPassengers
} else if (input$ticker =="ttrc"){
data(ttrc)
mydata1 <- ttrc
}
as.data.frame(mydata1)
})
df1 <- reactive({
year.ts <- as.numeric(year(input$date.ts))
month.ts <- as.numeric(month(input$date.ts))
dc <- decompose(AirPassengers)
df <- as.data.frame(dc[c("x","trend","seasonal","random")])
df2 <- data.frame(Date = index(dc$x),
apply(df, 2, as.numeric))
names(df2) <- c("Date", "Observed", "Trend", "Seasonal", "Random")
df2$Date <- as.Date(yearmon(df2$Date))
df2 <- as.xts(df2[,-c(1)],
order.by = df2$Date)
df2 <- round(df2, digits = 3)
df2
})
output$closing_prts <- renderHighchart({
df2 <- df1()
highchart(type = "stock") %>%
hc_title(text = "TIME SERIE DECOMPOSITION") %>%
hc_add_series(df2[, "Observed"], yAxis = 0, name = "Observed", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 1L, title = list(text = "Observed"), relative = 2) %>%
hc_add_series(df2[, "Trend"], yAxis = 1, type = "line",name = "Trend", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 2L, title = list(text = "Trend"), relative = 1)%>%
hc_add_series(df2[, "Seasonal"], yAxis = 2, type = "line",name = "Seasonal", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 1L, title = list(text = "Seasonal"), relative = 2) %>%
hc_add_series(df2[, "Random"], yAxis = 3, type = "line", name = "Random", showInLegend = FALSE) %>%
hc_add_yAxis(nid = 2L, title = list(text = "Random"), relative = 1)%>%
hc_exporting(
enabled = TRUE, # always enabled,
filename = paste0("Closing price decomposition line charts from ",
min(index(df2)),
" to ", max(index(df2))))%>%
hc_colors(colors = c("blue", "red", "cyan", "darkgreen"))
})
observeEvent(input$hideorshow, {
if ( input$hideorshow== "Show") {
shinyjs::show(id = "Sidebar")}
else {shinyjs::hide(id = "Sidebar")}
})
output$tbl1 <- renderDT({datatable(dt_new())})
output$summary1 <- renderPrint({
summary(dt_new())
})
output$struc<- renderPrint({
str(dt_new())
})
}
shinyApp(ui, server)
I am hoping for some help. I am the newest of the newbees and attempting to make this code work utilizing ShinyApp. Upon running my codes, I am receiving the error message of:
Warning: Error in $<-.data.frame: replacement has 0 rows, data has 1352
Is there anything that appears incorrect with my code that stands out? or any suggestions on next tries?
ui.R Code
library(shiny)
library(plotly)
library(DT)
mobility <- read.csv("mobility_data.csv", sep = ',')
mobility$Date <- as.Date(mobility$Date, format="%m/%d/%Y")
mobility$Province <- as.factor(mobility$Province)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
h2("COVID-19 Mobility Data"),
selectInput(inputId = "dv", label = "Category",
choices = c("Retail_Recreation", "Grocery_Pharmarcy", "Parks", "Transit_Stations", "Workplaces", "Residential"),
selected = "Grocery_Pharmarcy"),
selectInput(inputId = "provinces", "Province(s)",
choices = levels(mobility$Province),
multiple = TRUE,
selected = c("Utrecht", "Friesland", "Zeeland")),
dateRangeInput(inputId = "date", label = "Date range",
start = min(mobility$Date),
end = max(mobility$Date)),
downloadButton(outputId = "download_data", label = "Download"),
),
mainPanel(
plotlyOutput(outputId = "plot"),
em("Postive and negative percentages indicate an increase and decrease from the baseline period (median value between January 3 and February 6, 2020) respectively."),
DT::dataTableOutput(outputId = "table")
)
)
)
server.R code
server <- function(input, output) {
filtered_data <- reactive({
subset(mobility,
Province %in% input$provinces &
Date >= input$date[1] & Date <= input$date[2])})
output$plot <- renderPlotly({
ggplotly({
p <- ggplot(filtered_data(), aes_string(x = "Date", y = input$dv, color = "Province")) +
geom_point(alpha = 0.5) + theme(legend.position = "none") + ylab("% change from baseline")
p
})
})
output$table <- DT::renderDataTable({
filtered_data()
})
output$download_data <- downloadHandler(
filename = "Mobility_Data.csv",
content = function(file) {
data <- filtered_data()
write.csv(data, file, row.names = FALSE)
}
)
}
Here is the first seven rows from of sample data from my dataset entitled "mobility_data" as well:
structure(list(Country = c("Netherlands", "Netherlands", "Netherlands",
"Netherlands", "Netherlands", "Netherlands", "Netherlands"),
Province = c("Flevoland", "Flevoland", "Flevoland", "Flevoland",
"Flevoland", "Flevoland", "Flevoland"), Date = c("2/15/2020",
"2/16/2020", "2/17/2020", "2/18/2020", "2/19/2020", "2/20/2020",
"2/21/2020"), Retail_Recreation = c(-2L, -17L, 0L, 6L, 2L,
-2L, 4L), Grocery_Pharmarcy = c(-3L, -13L, -6L, -2L, -7L,
-5L, -1L), Parks = c(4L, -30L, 3L, 30L, 27L, 3L, 21L), Transit_Stations = c(5L,
-9L, -14L, -13L, -15L, -16L, -11L), Workplaces = c(-1L, -7L,
-19L, -18L, -18L, -20L, -21L), Residential = c(0L, 1L, 3L,
3L, 2L, 3L, 2L)), row.names = c(NA, 7L), class = "data.frame")
You can read the csv file using fileInput. Try this
library(shiny)
library(plotly)
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
h2("COVID-19 Mobility Data"),
fileInput("file1", "Choose CSV file to upload", accept = ".csv"),
selectInput(inputId = "dv", label = "Category",
choices = c("Retail_Recreation", "Grocery_Pharmarcy", "Parks", "Transit_Stations", "Workplaces", "Residential"),
selected = "Grocery_Pharmarcy"),
selectInput(inputId = "provinces", "Province(s)",
choices = levels(mobility$Province),
multiple = TRUE,
selected = c("Utrecht", "Friesland", "Zeeland")),
dateRangeInput(inputId = "date", label = "Date range",
start = min(mobility$Date),
end = max(mobility$Date)),
downloadButton(outputId = "download_data", label = "Download"),
),
mainPanel(
plotlyOutput(outputId = "plot"),
em("Postive and negative percentages indicate an increase and decrease from the baseline period (median value between January 3 and February 6, 2020) respectively."),
DT::dataTableOutput(outputId = "table")
)
)
)
server <- function(input, output) {
mobility <- reactive({
infile <- input$file1
req(infile)
return(read.csv(infile$datapath, header=TRUE, sep=','))
})
filtered_data <- reactive({
subset(mobility(),
Province %in% input$provinces &
Date >= input$date[1] & Date <= input$date[2])})
output$plot <- renderPlotly({
ggplotly({
p <- ggplot(filtered_data(), aes_string(x = "Date", y = input$dv, color = "Province")) +
geom_point(alpha = 0.5) + theme(legend.position = "none") + ylab("% change from baseline")
p
})
})
output$table <- DT::renderDataTable({
filtered_data()
})
output$download_data <- downloadHandler(
filename = "Mobility_Data.csv",
content = function(file) {
data <- filtered_data()
write.csv(data, file, row.names = FALSE)
}
)
}
shinyApp(ui, server)
I have an application which works fine locally and I would like to deploy it to shinyapps.io. I created a directory (dataviz) and the application code is in a file called app.R. When running deployApp("dataviz") from RStudio, it starts deploying but reaches a point where it fails with the error:
** preparing package for lazy loading
Error in loadNamespace(i, c(lib.loc, .libPaths()), versionCheck = vI[[i]]) :
there is no package called ‘htmltools’
ERROR: lazy loading failed for package ‘rcdimple’
* removing ‘/usr/local/lib/R/site-library/rcdimple’
################################### End Log ###################################
Error: Unhandled Exception: Child Task 27328802 failed: Error building image: Error building rcdimple (0.1). Build exited with non-zero status: 1
Not sure what could be happening here, any help greatly appreciated.
The app.R is as so
## app.R ##
library(shinydashboard)
library(shiny)
require(htmltools)
require(htmlwidgets)
library(rcdimple) #devtools::install_github("timelyportfolio/rcdimple")
library(curl) #devtools::install_github("jeroenooms/curl")
library(plyr) # for round_any
library(rCharts)
library(ggvis)
library(reshape2)
indicators <- read.csv(curl("https://raw.githubusercontent.com/kilimba/msc-impl-R/master/dataviz/data/testindicators.csv"))
choices <- as.vector(indicators$label)
indicators$label <- as.character(indicators$label)
indicators$file <- paste("",indicators$file,"",sep="")
getHeatMapData <- function(data,indicator){
df <- data
if(indicator$rate == "Y"){
hmap_df <- aggregate(cbind(denominator,numerator) ~ year + agegrp,df,sum)
hmap_df$rate <- round((hmap_df$numerator/hmap_df$denominator)*indicator$multiplier,2)
names(hmap_df)
}else{
hmap_df <- aggregate(denominator ~ agegrp + year,df, sum)
}
hmap_df$year <- factor(hmap_df$year)
# Helps to order the y-axis labels otherwise labels appear in mixed order
hmap_df$agegrp <- factor(hmap_df$agegrp, levels = rev(as.vector(unique(hmap_df$agegrp))))
return(hmap_df)
}
getData <- function(startyr,endyear,outcome_data) {
data <- subset(outcome_data,(year >= startyr & year <= endyear))
return(data)
}
getDataByAgeGroup <-function(data,agegrp){
d <- data
a <- agegrp
selection <- subset(d,agegrp==a)
return(selection)
}
lineChart <- function(data,agegrp,indicator){
if(indicator$rate == "Y"){
selection <- data
selection$rate <- round((selection$numerator/selection$denominator)*indicator$multiplier,2)
selection$sex <- ifelse(selection$sex == 1, "MALE", "FEMALE")
max_y <- round_any(max(selection$rate), 10, f = ceiling)
min_y <- round_any(min(selection$rate), 10, f = floor)
selection <- getDataByAgeGroup(selection,agegrp)
plot <- nPlot(rate ~ year,
data = selection,
type = "lineChart",
group = "sex",
height = 250,
width = 450 )
# Explicitly set year tick values for every year
plot$xAxis(tickValues = do.call(seq, c(as.list(range(selection$year)), 1)),rotateLabels= -40,showMaxMin = "true")
plot$chart(useInteractiveGuideline = "true", transitionDuration = 500)
plot$chart(forceY = c(min_y, max_y))
plot$chart(color = c("steelblue","firebrick"))
# Add axis labels and format the tooltip
plot$yAxis(axisLabel = paste("Rate per",indicator$multiplier), width = 62)
plot$xAxis(axisLabel = "Year")
return(plot)
}else{
selection <- data
selection$sex <- ifelse(selection$sex == 1, "MALE", "FEMALE")
max_y <- round_any(max(selection$denominator), 10, f = ceiling)
min_y <- round_any(min(selection$denominator), 10, f = floor)
selection <- getDataByAgeGroup(selection,agegrp)
plot <- nPlot(denominator ~ year,
data = selection,
type = "lineChart",
group = "sex",
height = 250,
width = 450 )
# Explicitly set year tick values for every year
plot$xAxis(tickValues = do.call(seq, c(as.list(range(selection$year)), 1)),rotateLabels= -40,showMaxMin = "true")
plot$chart(useInteractiveGuideline = "true", transitionDuration = 500)
plot$chart(forceY = c(min_y, max_y))
plot$chart(color = c("steelblue","firebrick"))
# Add axis labels and format the tooltip
plot$yAxis(axisLabel = "Population", width = 62)
plot$xAxis(axisLabel = "Year")
return(plot)
}
}
# Heat Map
heatmap <- function(data,indicator){
dat <- getHeatMapData(data,indicator)
if(indicator$rate == "Y"){
dat <- rename(dat, c("agegrp" = "Age","year" = "Year", "rate" = "Rate"))
dat %>%
ggvis(~Year, ~Age, fill = ~Rate) %>%
layer_rects(width = band(), height = band()) %>%
add_relative_scales() %>%
set_options(height = 200, width = 410, keep_aspect = TRUE) %>%
add_axis("y", title="")%>%
scale_nominal("x", padding = 0, points = FALSE) %>%
scale_nominal("y", padding = 0, points = FALSE) %>%
scale_numeric("fill",range = c("lightsteelblue","red")) %>%
hide_legend("fill") %>%
add_tooltip(function(d) {
if(is.null(d)) return(NULL)
paste0(names(d), ": ", format(d), collapse = "<br />")
}
) %>%
bind_shiny("heatmap")
}else{
dat <- rename(dat, c("agegrp" = "Age","year" = "Year", "denominator" = "Count"))
dat %>%
ggvis(~Year, ~Age, fill = ~Count) %>%
layer_rects(width = band(), height = band()) %>%
add_relative_scales() %>%
set_options(height = 200, width = 410, keep_aspect = TRUE) %>%
add_axis("y", title="")%>%
scale_nominal("x", padding = 0, points = FALSE) %>%
scale_nominal("y", padding = 0, points = FALSE) %>%
scale_numeric("fill",range = c("lightsteelblue","red")) %>%
hide_legend("fill") %>%
add_tooltip(function(d) {
if(is.null(d)) return(NULL)
paste0(names(d), ": ", format(d), collapse = "<br />")
}
) %>%
bind_shiny("heatmap")
}
}
# DimpleJS pyramid
dPyramid <- function(startyear, endyear, data, colors=c("steelblue","firebrick"),indicator) {
dat <- getData(startyear,endyear,data)
if(indicator$rate == "Y"){
dat$denominator <- ifelse(dat$sex == 1, -1 * dat$denominator, 1 * dat$denominator)
dat$Gender <- ifelse(dat$sex == 1,"Male", "Female")
dat$Rate <- (dat$numerator/dat$denominator)*indicator$multiplier
max_x <- round_any(max(dat$Rate), 10, f = ceiling)
min_x <- round_any(min(dat$Rate), 10, f = floor)
dat <- rename(dat, c("agegrp" = "Age"))
d1 <- dimple(
x = "Rate",
y = "Age",
groups = "Gender",
data = dat,
type = 'bar')
d1 <- yAxis(d1, type = "addCategoryAxis", orderRule = "Age")
d1 <- xAxis(d1,type = "addMeasureAxis")
# Ensure fixed x-axis independent of year selected
d1 <- xAxis(d1, overrideMax = max_x, overrideMin = min_x)
if (!is.null(colors)){
d1 <- colorAxis(
d1,
type = "addColorAxis",
colorSeries = "sex",
palette = colors
)
}
# For storyboarding
if (endyear - startyear >= 1) {
d1 <- tack(d1, options = list( storyboard = "year" ) )
}
return(d1)
}
else{
dat$denominator <- ifelse(dat$sex == 1, -1 * dat$denominator, 1 * dat$denominator)
dat$Gender <- ifelse(dat$sex == 1,"Male", "Female")
max_x <- round_any(max(dat$denominator), 10, f = ceiling)
min_x <- round_any(min(-1*dat$denominator), 10, f = floor)
dat <- rename(dat,c("denominator" = "Count","agegrp" = "Age"))
d1 <- dimple(
x = "Count",
y = "Age",
groups = "Gender",
data = dat,
type = 'bar')
d1 <- yAxis(d1, type = "addCategoryAxis", orderRule = "Age")
d1 <- xAxis(d1,type = "addMeasureAxis")
# Ensure fixed x-axis independent of year selected
d1 <- xAxis(d1, overrideMax = max_x, overrideMin = min_x)
if (!is.null(colors)){
d1 <- colorAxis(
d1,
type = "addColorAxis",
colorSeries = "sex",
palette = colors
)
}
# For storyboarding
if (endyear - startyear >= 1) {
d1 <- tack(d1, options = list( storyboard = "year" ) )
}
return(d1)
}
}
suppressMessages(
singleton(
addResourcePath(
get_lib("nvd3")$name
,get_lib("nvd3")$url
)
)
)
ui <- dashboardPage(
dashboardHeader(title = "HealthData Viz"),
dashboardSidebar(
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
menuItem("Presentations", tabName = "widgets", icon = icon("file-powerpoint-o"))
),
tags$br(),
tags$fieldset(checkboxInput("doAnimate", "Animate Pyramid",value = TRUE),
tags$p("(Uncheck to select specific year)")),
conditionalPanel(
condition = "input.doAnimate == false",
uiOutput("choose_year")
),
uiOutput("choose_agegrp")
,
uiOutput("choose_dataset")
),
dashboardBody(
tags$head(get_assets_shiny(get_lib("nvd3"))[-3]),
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
box(dimpleOutput("distPlot", height = 250)),
box(showOutput("distPlot2","nvd3",add_lib=F))
),
fluidRow(
#box(infoBoxOutput("informationBox")),
infoBox("About", textOutput("caption"), icon = icon("info-circle"),width = 6),
(
#uiOutput("ggvis_ui"),
box(ggvisOutput("heatmap"))
)
)
),
# Second tab content
tabItem(tabName = "widgets",
h2("Links to interactive scientific presentations will go here...")
)
)
)
)
server <- function(input, output) {
output$choose_dataset <- renderUI({
selectInput("outcome", "Select Outcome", choices, selected="Population Structure",width="95%")
})
output$choose_agegrp <- renderUI({
selectInput("agegrp", "Select Age Group",
choices = c("00-04","05-09","10-14","15-19","20-24","25-29",
"30-34","35-39","40-44","45-49","50-54",
"55-59","60-64","65-69","70-74","75-79",
"80-84","85+"), selected="00-04",width="95%")
})
#############################################################
# PYRAMID
#############################################################
observe({
if(!is.null(input$outcome)){
selected_outcome <- input$outcome
selected_indicator <- subset(indicators,indicators$label == selected_outcome)
outcome_data <- reactive({
read.csv(curl(as.character(selected_indicator$file)))
})
d <- reactive({outcome_data()})
minYear <- reactive({min(d()$year)})
maxYear <- reactive({max(d()$year)})
observe({
if(input$doAnimate){
output$distPlot <- renderDimple({
dPyramid(minYear(), maxYear(),data = outcome_data(), indicator = selected_indicator)
})
}else{
years <- as.vector(unique(outcome_data()$year))
output$choose_year <- renderUI({
selectInput("startyr", "Select Pyramid Year", years, width="95%")
})
output$distPlot <- renderDimple({
if(!is.null(input$startyr)){
startyear <- as.numeric(input$startyr)
# Start year and end year are equal we only want cross-sectional pyramid
# for a single selected year
dPyramid(startyear, startyear, data = outcome_data(),indicator = selected_indicator)
}
})
}
})
}
})
###############################################
observe({
if(!is.null(input$outcome)
& !is.null(input$agegrp)){
selected_outcome <- input$outcome
selected_indicator <- subset(indicators,indicators$label == selected_outcome)
outcome_data <- reactive({
read.csv(curl(as.character(selected_indicator$file)))
})
d <- reactive({outcome_data()})
output$caption <- renderText({
return(paste("You are currently viewing",
ifelse(selected_indicator$rate=="N",paste(input$outcome,".\n",selected_indicator$description),
paste(input$outcome,"(per",selected_indicator$multiplier,"population).\n",selected_indicator$description))))
})
################################################
# Line chart
################################################
output$distPlot2 <- renderChart2({
lineChart(outcome_data(),input$agegrp,selected_indicator)
})
#################################################
# HEATMAP
#################################################
heatmap(outcome_data(),selected_indicator)
}
})
}
shinyApp(ui, server)
Tumaini
#timelyportfolio - It seems dependencies to htmltools was not listed in the DESCRIPTION file of the rcdimple package. Forked the package from https://github.com/timelyportfolio/rcdimple and added the dependencies to the DESCRIPTION file (https://github.com/kilimba/rcdimple). Can now deploy a shiny app which uses the rcdimple package to shinayapps.io. Have made a Pull Request to master branch