I have been messing with making a shiny app and I feel as though i am doing everything in the correct manner to get the table to render but no luck. In my app you should you upload an csv and then go to the data frame tab. I have tried many small changes but nothing seems to work. Id imagine this has something to do with the server section but i cant see it.
R ui:
library(readxl)
library(plyr)
library(dplyr)
library(plotly)
library(readr)
library(RColorBrewer)
library(data.table)
library(shiny)
library(shinydashboard)
library(shinythemes)
library(leaflet)
library(DT)
library(xtable)
ui <- fluidPage(theme = shinytheme("slate"), mainPanel(
navbarPage(
"Permian Plots", collapsible = TRUE, fluid = TRUE,
navbarMenu(
"County Plot",
tabPanel(
sidebarPanel( fileInput(
'file1',
'Choose CSV File',
accept = c('text/csv', 'text/comma-separated-values,text/plain', '.csv')
),
tags$hr(),
checkboxInput('header', 'Header', TRUE),
# App buttons comma and quote
radioButtons('sep', 'Separator',
c(
Comma = ',',
Semicolon = ';',
Tab = '\t'
), ','),
radioButtons(
'quote',
'Quote',
c(
None = '',
'Double Quote' = '"',
'Single Quote' = "'"
),
'"'
))
),
tabPanel("Data Frame",
fluidRow(box(DT::dataTableOutput("contents")))),
tabPanel("County Plot", plotlyOutput(
"plotMap", height = 1200, width = 1200
),
actionButton("btn", "Plot")
)
)
)
)
)
Server:
server <- function(input, output, session) {
options(shiny.maxRequestSize = 200*1024^2)
dsnames <- c()
data_set <- reactive({
inFile <- input$file1
if (is.null(inFile)){
return()
}
data_set <- read.csv(
inFile$datapath,
header = input$header,
sep = input$sep,
quote = input$quote
)
})
output$contents <- DT::renderDataTable({
withProgress(message = 'loading...', value = 0.1, {
datatable(data_set(),
options = list(
"pageLength" = 40))
extensions = 'Responsive'
setProgress(1)
})
})
output$choose_dataset <- renderUI({
selectInput("dataset", "Data set", as.list(data_sets))
})
observeEvent(
input$btn,
{
output$plotMap <- renderPlotly({withProgress(message = 'Plotting...', value = 0.1,{
plot <- Plots(data_set(),
"Martin County",
"~/Work/permin/martin county/martin data/f1.csv",
"~/Work/permin/BestMartinPlotSat.html",
32.1511, -101.5715)
setProgress(1)
})
})
}
)
}
shinyApp(ui = ui, server = server)
Function:
Should not be the problem causer in this.
Plots <- function(df, C_name, PathCSV, PathWidg, Lat, Lon){
f1 <- df
f1$Date <- as.POSIXct(f1$Date)
f1$year <- format(as.POSIXct(f1$Date,format="%y-%m-%d"), "%y")
f1$month <- format(as.POSIXct(f1$Date,format="%y-%m-%d"), "%m")
f1$Cell <- as.factor(f1$Cell)
z <- ddply(f1, c("year", "month", "Cell"), summarise,
yearMonth_Max_sum = max(`Cell Sum (Norm)`))
f1 <- inner_join(f1,z, by = c("year", "month", "Cell"))
f1$Changed <- as.numeric(as.factor(f1$Changed))
f1$Changed[f1$Changed == 1] <- 0
f1$Changed[f1$Changed == 2] <- 1
z <- ddply(f1, c("year", "month", "Cell"), summarise,
ChangedX = max(Changed))
f1 <- inner_join(f1,z, by = c("year", "month", "Cell"))
f1$MY <- paste(f1$year, f1$month, sep = "-")
#preapring data for plotly
q <- matrix(quantile(f1$StdDev))
f1$qunat <- NA
up <- matrix(quantile(f1$StdDev, probs = .95))
up
f1$qunat <- ifelse((f1$StdDev > q[4:4,1]) & (f1$StdDev < up[1,1]), 1, 0)
z <- group_by(f1, Cell) %>%
summarize(Median_Cell = median(`Cell Sum (Norm)`, na.rm = FALSE))
f1 <- inner_join(f1,z, by = c("Cell"))
quantile(round(f1$Median_Cell))
f1$NewMedian <- NA
f1$NewMedian[f1$Median_Cell > 4000] <- 0
f1$NewMedian[f1$Median_Cell <= 4000] <- 1
f1$NewSum <- NA
f1$NewSum <- f1$yearMonth_Max_sum * f1$ChangedX * f1$qunat * f1$NewMedian
write_csv(f1, PathCSV )
f2 <- f1[!duplicated(f1$yearMonth_Max_sum), ]
#plolty plot
Sys.setenv('MAPBOX_TOKEN' = 'pk.eyJ1IjoiY3dvb2RzMjIiLCJhIjoiY2prMnlycmduMDJvNjNxdDEzczNjdGt3YSJ9.RNuCSlHyKZpkTQ8mJmg4aw')
p <- f2[which(f2$yearMonth_Max_sum < 9000),] %>%
plot_mapbox(
lon = ~Lon,
lat = ~Lat,
size = ~yearMonth_Max_sum,
color = ~(NewSum),
frame = ~MY,
type = 'scattermapbox',
mode = 'markers',
colors = c("green","blue")
) %>%
add_markers(text = ~paste("Sum", yearMonth_Max_sum, "/<br>",
"Standard Dev", StdDev, "/<br>",
"Mean", Average, "/<br>",
"Median", Median_Cell, "/<br>",
"Changed", ChangedX, "/<br>",
"Latitude", Lat , "/<br>",
"Longitude", Lon)) %>%
layout(title = C_name,
font = list(color = "black"),
mapbox = list(style = "satellite", zoom = 9,
center = list(lat = Lat,
lon = Lon)))
p
htmlwidgets::saveWidget(p, PathWidg)
}
the last thing in your function is what is returned. you are returning setprogress(1) to renderdatatable()
output$contents <- DT::renderDataTable({
withProgress(message = 'loading...', value = 0.1, {
datatable(data_set(),
options = list(
"pageLength" = 40))
extensions = 'Responsive'
setProgress(1)
})
Try this instead
output$contents <- DT::renderDataTable({
withProgress(message = 'loading...', value = 0.1, {
datatab <- datatable(data_set(),
options = list(
"pageLength" = 40))
extensions = 'Responsive'
setProgress(1)
datatab
})
Related
I'm working on a table rendered with rhandsontable that uses dropdown menus for user inputs into the table. My dropdown approach is based on guidance provided in post Is there a way to have different dropdown options for different rows in an rhandsontable?. I'm trying to add a feature where the user clicks on an actionButton() in order to add a column to the table and sequentially numbers the header for the added column, with the dropdowns included in the added column. The below code almost works, except that added columns don't have the required dropdowns. What am I doing wrong here?
Code:
library(shiny)
library(rhandsontable)
ui <- fluidPage(br(),
mainPanel(
actionButton("add", "Add column"),br(),br(),
rHandsontableOutput("Tbl")
)
)
server <- function(input, output) {
DF <- reactiveVal(
data.frame(
'Series 1' = NA_character_,
stringsAsFactors = FALSE,
row.names = c("Select option"),
check.names = FALSE
)
)
observeEvent(input$Tbl,{DF(hot_to_r(input$Tbl))})
output$Tbl <- renderRHandsontable({
select_option <- c(NA_character_, "dog", "cat") # defines the dropdown options
tmp <- rhandsontable(DF(), rowHeaderWidth = 200, selectCallback = TRUE, height = 300) %>%
hot_cols(colWidths = 100) %>%
hot_col("Series 1",
allowInvalid = FALSE,
type = "dropdown",
source = NA_character_,
readOnly = TRUE
)
tmp <- hot_col(tmp,
col = "Series 1",
allowInvalid = FALSE,
type = "dropdown",
source = select_option
) %>%
hot_cell(row = input$Tbl_select$select$r, col = "Series 1", readOnly = FALSE)
tmp
})
observeEvent(input$add, {
select_option <- c(NA_character_, "dog", "cat") # defines the dropdown options
newCol <- data.frame('Series 1' = NA_character_,stringsAsFactors = FALSE)
names(newCol) <- paste("Series", ncol(hot_to_r(input$Tbl)) + 1)
DF(cbind(DF(), newCol))
})
}
shinyApp(ui = ui, server = server)
You need to apply hot_col(type = "dropdown") on every column of the reactive data.frame (col = names(DF())) not only on the first col = "Series 1":
library(shiny)
library(rhandsontable)
ui <- fluidPage(br(),
mainPanel(
actionButton("add", "Add column"),br(),br(),
rHandsontableOutput("Tbl")
)
)
server <- function(input, output) {
DF <- reactiveVal(
data.frame(
'Series 1' = NA_character_,
stringsAsFactors = FALSE,
row.names = c("Select option"),
check.names = FALSE
)
)
observeEvent(input$Tbl,{DF(hot_to_r(input$Tbl))})
output$Tbl <- renderRHandsontable({
select_option <- c(NA_character_, "dog", "cat") # defines the dropdown options
rhandsontable(DF(), rowHeaderWidth = 200, selectCallback = TRUE, height = 300) %>%
hot_cols(colWidths = 100) %>%
hot_col(col = names(DF()),
allowInvalid = FALSE,
type = "dropdown",
source = select_option
) %>%
hot_cell(row = input$Tbl_select$select$r, col = "Series 1", readOnly = FALSE)
})
observeEvent(input$add, {
select_option <- c(NA_character_, "dog", "cat") # defines the dropdown options
newCol <- data.frame('Series 1' = NA_character_,stringsAsFactors = FALSE)
names(newCol) <- paste("Series", ncol(hot_to_r(input$Tbl)) + 1)
DF(cbind(DF(), newCol))
})
}
shinyApp(ui = ui, server = server)
Following up on ismirsehregal's solution for column addition, the below offers both column addition and deletion via actionButton():
library(shiny)
library(rhandsontable)
ui <- fluidPage(br(),
mainPanel(
actionButton("add", "Add column"),br(),br(),
actionButton("delSeries","Select series below to delete"),
uiOutput("delSeries2"),
rHandsontableOutput("Tbl")
)
)
server <- function(input, output) {
DF <- reactiveVal(
data.frame(
'Series 1' = NA_character_,
stringsAsFactors = FALSE,
row.names = c("Select option"),
check.names = FALSE
)
)
observeEvent(input$Tbl,{DF(hot_to_r(input$Tbl))})
output$Tbl <- renderRHandsontable({
select_option <- c(NA_character_, "dog", "cat") # defines the dropdown options
tmp <- rhandsontable(DF(), rowHeaderWidth = 200, selectCallback = TRUE, height = 300) %>%
hot_cols(colWidths = 100) %>%
hot_col("Series 1",
allowInvalid = FALSE,
type = "dropdown",
source = NA_character_,
readOnly = TRUE
)
tmp <- hot_col(tmp,
col = names(DF()), # adding this is what fixed it
allowInvalid = FALSE,
type = "dropdown",
source = select_option
) %>%
hot_cell(row = input$Tbl_select$select$r, col = "Series 1", readOnly = FALSE)
tmp
})
observeEvent(input$add, {
newCol <- data.frame('Series 1' = NA_character_,stringsAsFactors = FALSE)
names(newCol) <- paste("Series", ncol(hot_to_r(input$Tbl)) + 1)
DF(cbind(DF(), newCol))
})
observeEvent(input$delSeries3, {
tmp <- DF()
delCol <- input$delSeries3
tmp <- tmp[ , !(names(tmp) %in% delCol), drop = FALSE]
newNames <- sprintf("Series %d",seq(1:ncol(tmp)))
names(tmp) <- newNames
DF(tmp)
})
output$delSeries2 <-
renderUI(
selectInput("delSeries3",
label = NULL,
choices = colnames(hot_to_r(input$Tbl)),
selected = "",
multiple = TRUE,
width = '110px')
)
}
shinyApp(ui = ui, server = server)
I am putting together an Shiny app to allow users to upload an area of interest (AOI), and calculate the amount of overlap with an administrative boundary (WMU). Everything is working as desired, except that my picker input options do not update. The picker input works, but I would like the choices to only include the WMU that overlap the AOI instead of all possible WMU. I can calculate the WMU ID that should populate the list, shown in the "TEST_TEXT"output below the map frame, but cannot successfully update the pickerInput. This kmz will overlap the several WMU that are loaded at the beginning of the script included below:
library(shiny)
library(sf)
library(tidyverse)
library(bcdata)
library(shinyjs)
library(leaflet)
library(mapview)
library(DT)
library(pals)
library(shinyWidgets)
library(shinymanager)
WMU_DATA <-
bcdc_get_data("wildlife-management-units") %>% st_transform(4326) %>% mutate(Total.WMU.HA =
as.numeric(st_area(.)) / 10000)
##### UI #####
ui <- fluidPage(
tags$head(tags$style(
HTML(
".shiny-notification {
height: 100px;
width: 400px;
position:fixed;
top: calc(25% - 50px);;
left: calc(50% - 200px);;
}
"
)
)),
# Application title
titlePanel("Calculate Overlap With WMU"),
# Inputs
sidebarLayout(
sidebarPanel(
width = 3,
textInput(
inputId = "AOI_NAME",
label = "AOI Name",
value = NULL
),
HTML("<br><br>"),
fileInput(
inputId = "KMZ",
label = "Choose KMZ",
multiple = FALSE,
accept = c('.kmz')
),
h3("or"),
HTML("<br><br>"),
fileInput(
inputId = "SHAPEFILE",
label = "Choose shapefile",
multiple = TRUE,
accept = c('.shp', '.dbf', '.sbn', '.sbx', '.shx', '.prj', '.xml')
),
pickerInput(
inputId = "WMU_FILTER",
label = "Filter Overlapping WMU",
choices = unique(WMU_DATA$WILDLIFE_MGMT_UNIT_ID),
selected = unique(WMU_DATA$WILDLIFE_MGMT_UNIT_ID),
multiple = TRUE,
options = list(`actions-box` = TRUE)
),
HTML("<br><br>")
),
# Display OUtputs
mainPanel(
width = 9,
leafletOutput("OVERLAP_MAP", height = 750),
h3(textOutput("TEST_TEXT")),
DTOutput("AOI_OVERLAP_TABLE")
)
)
)
######server#####
server <- function(input, output, session) {
####reactive data
AOI <-
reactive({
if (is.null(input$SHAPEFILE) & !is.null(input$KMZ)) {
st_read(unzip(input$KMZ$datapath)) %>%
st_zm(drop = T) %>%
mutate(AOI_NAME = input$AOI_NAME) %>%
st_transform(4326) %>%
select(-Name)
}
else if (!is.null(input$SHAPEFILE) & is.null(input$KMZ)) {
SHAPEFILE()
}
else{
return(NULL)
}
})
WMU_OVERLAP <- reactive({
st_filter(WMU_DATA, AOI())
})
AOI_WMU_INTERSECT <-
reactive({
st_intersection(AOI(), WMU_OVERLAP()) %>%
mutate(`HA of Overlap` = round(as.numeric(st_area(.)) / 10000, 0)) %>%
mutate(`Percent of WMU` = round(`HA of Overlap` / `Total.WMU.HA` *
100, 2))
})
observeEvent(AOI_WMU_INTERSECT
,
{
updatePickerInput(
session,
"WMU_FILTER",
choices = unique(AOI_WMU_INTERSECT()$WILDLIFE_MGMT_UNIT_ID),
selected = unique(AOI_WMU_INTERSECT()$WILDLIFE_MGMT_UNIT_ID)
)
},
ignoreInit = TRUE,
ignoreNULL = TRUE)
###outputs
output$OVERLAP_MAP <-
renderLeaflet({
withProgress(message = "Calcualting Overlap", detail = "Should be done soon", {
AOI_SPATIAL <- AOI() %>% mutate(AOI_NAME = input$AOI_NAME)
WMU <-
WMU_OVERLAP() %>% filter(WILDLIFE_MGMT_UNIT_ID %in% input$WMU_FILTER)
Overlap <-
AOI_WMU_INTERSECT() %>% filter(WILDLIFE_MGMT_UNIT_ID %in% input$WMU_FILTER)
MAP <-
mapview(
Overlap,
zcol = "WILDLIFE_MGMT_UNIT_ID",
alpha.regions = 0.2,
map.types = c("Esri.WorldTopoMap", "Esri.WorldImagery"),
col.regions = alphabet(nlevels(
as.factor(WMU$WILDLIFE_MGMT_UNIT_ID)
))
) +
mapview(
WMU,
zcol = "WILDLIFE_MGMT_UNIT_ID",
alpha.regions = 0.2,
lwd = 3,
col.regions = alphabet(nlevels(
as.factor(WMU$WILDLIFE_MGMT_UNIT_ID)
)),
hide = TRUE
) +
mapview(AOI_SPATIAL,
label = "AOI_NAME",
col.regions = "red")
MAP#map %>%
setView(st_coordinates(st_centroid(st_as_sfc(
st_bbox(AOI_SPATIAL)
)))[, 1],
st_coordinates(st_centroid(st_as_sfc(
st_bbox(AOI_SPATIAL)
)))[, 2],
zoom = 9)
})
})
output$AOI_OVERLAP_TABLE <-
renderDT({
AOI_OVERLAP_TABLE <- AOI_WMU_INTERSECT() %>%
st_drop_geometry()
AOI_OVERLAP_TABLE
}, filter = "top", extensions = c("FixedHeader", "Buttons"),
options = list(
pageLength = 100,
fixedHeader = TRUE,
dom = "Bfrtip",
buttons = c('colvis', 'copy', 'excel', 'csv')
))
output$TEST_TEXT <-
renderText(unique(AOI_WMU_INTERSECT()$WILDLIFE_MGMT_UNIT_ID))
}
# Run the application
shinyApp(ui = ui, server = server)
Putting some req() and changing observeEvent() to observe() makes it work. Try this
######server#####
server <- function(input, output, session) {
####reactive data
AOI <-
reactive({
if (is.null(input$SHAPEFILE) & !is.null(input$KMZ)) {
st_read(unzip(input$KMZ$datapath)) %>%
st_zm(drop = T) %>%
mutate(AOI_NAME = input$AOI_NAME) %>%
st_transform(4326) %>%
select(-Name)
}
else if (!is.null(input$SHAPEFILE) & is.null(input$KMZ)) {
SHAPEFILE()
}
else{
return(NULL)
}
})
WMU_OVERLAP <- reactive({
req(AOI())
st_filter(WMU_DATA, AOI())
})
AOI_WMU_INTERSECT <-
reactive({
req(AOI(), WMU_OVERLAP())
st_intersection(AOI(), WMU_OVERLAP()) %>%
dplyr::mutate(`HA of Overlap` = round(as.numeric(st_area(.)) / 10000, 0)) %>%
dplyr::mutate(`Percent of WMU` = round(`HA of Overlap` / `Total.WMU.HA` *100, 2))
})
observe({updatePickerInput(
session,
"WMU_FILTER",
choices = unique(AOI_WMU_INTERSECT()$WILDLIFE_MGMT_UNIT_ID),
selected = unique(AOI_WMU_INTERSECT()$WILDLIFE_MGMT_UNIT_ID)
)
} )#, ignoreInit = TRUE, ignoreNULL = TRUE)
###outputs
output$OVERLAP_MAP <-
renderLeaflet({
req(AOI_WMU_INTERSECT())
withProgress(message = "Calcualting Overlap", detail = "Should be done soon", {
AOI_SPATIAL <- AOI() %>% dplyr::mutate(AOI_NAME = input$AOI_NAME)
WMU <-
WMU_OVERLAP() %>% dplyr::filter(WILDLIFE_MGMT_UNIT_ID %in% input$WMU_FILTER)
Overlap <-
AOI_WMU_INTERSECT() %>% dplyr::filter(WILDLIFE_MGMT_UNIT_ID %in% input$WMU_FILTER)
MAP <-
mapview(
Overlap,
zcol = "WILDLIFE_MGMT_UNIT_ID",
alpha.regions = 0.2,
map.types = c("Esri.WorldTopoMap", "Esri.WorldImagery"),
col.regions = alphabet(nlevels(
as.factor(WMU$WILDLIFE_MGMT_UNIT_ID)
))
) +
mapview(
WMU,
zcol = "WILDLIFE_MGMT_UNIT_ID",
alpha.regions = 0.2,
lwd = 3,
col.regions = alphabet(nlevels(
as.factor(WMU$WILDLIFE_MGMT_UNIT_ID)
)),
hide = TRUE
) +
mapview(AOI_SPATIAL,
label = "AOI_NAME",
col.regions = "red")
MAP#map %>%
setView(st_coordinates(st_centroid(st_as_sfc(
st_bbox(AOI_SPATIAL)
)))[, 1],
st_coordinates(st_centroid(st_as_sfc(
st_bbox(AOI_SPATIAL)
)))[, 2],
zoom = 9)
})
})
output$AOI_OVERLAP_TABLE <-
renderDT({
AOI_OVERLAP_TABLE <- AOI_WMU_INTERSECT() %>% st_drop_geometry()
AOI_OVERLAP_TABLE
}, filter = "top", extensions = c("FixedHeader", "Buttons"),
options = list(
pageLength = 100,
fixedHeader = TRUE,
dom = "Bfrtip",
buttons = c('colvis', 'copy', 'excel', 'csv')
))
output$TEST_TEXT <- renderText(unique(AOI_WMU_INTERSECT()$WILDLIFE_MGMT_UNIT_ID))
}
I created an application in Shiny where I would like to choose multiple items from the drop-down menu. Unfortunately, I don't know how to make items on the list reduce after a given menu selection. By which all lines merge into a whole. what should I add in the code so that each model is a separate line. Below I put a picture with charts.
My code:
library(shiny)
library(plotly)
library(readxl)
library(shinyWidgets)
library(shinydashboard)
library(shinyjs)
library(DT)
df1 <- data.frame(Month = rep(month.abb[1:12],10,replace = TRUE), Model = paste0('Ferrari ', rep(LETTERS[1:10], each = 12)),
Value = sample(c(0:300),120, replace = T),
Car = rep('Ferrari', 10,each = 12), Year = rep(2019:2020, each = 60),Country = rep(c("USA","DE"), each = 12, times = 5), stringsAsFactors = F)
df2 <- data.frame(Month = rep(month.abb[1:12],10,replace = TRUE), Model = paste0('Porsche ', rep(LETTERS[1:10], each = 12)),
Value = sample(c(0:300),120, replace = T),
Car = rep('Porsche', 10,each = 12), Year = rep(2019:2020, each = 60), Country = rep(c("USA","DE"), each = 12, times = 5),stringsAsFactors = F)
data <-rbind(df1, df2)
ui <- fluidPage(
titlePanel("Test"),
sidebarLayout(
sidebarPanel( width = 3,
uiOutput("category1"),
uiOutput("category2"),
uiOutput("category3"),
uiOutput("category4")),
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Plot", plotlyOutput("plot", height = 550,width = 1000))
)
)
)
)
server <- function(input, output,session) {
output$category1 <- renderUI({
selectInput('cat1', 'Choose year:', multiple = T, selected = NULL, choices = sort(as.numeric(unique(data$Year))))
})
df_subset <- eventReactive(input$cat1,{
if(input$cat1=="All") {df_subset <- data}
else{df_subset <- data[data$Year == input$cat1,]}
})
df_subset1 <- reactive({
if(is.null(input$cat2)){df_subset()} else {df_subset()[df_subset()$Country %in% input$cat2,]}
})
output$category2 <- renderUI({
selectInput('cat2', 'Choose country:', choices = sort(as.character(unique(df_subset()$Country))), multiple = T, selected = NULL)
})
df_subset2 <- reactive({
if(is.null(input$cat3)){df_subset1()} else {df_subset1()[df_subset1()$Car %in% input$cat3,]}
})
output$category3 <- renderUI({
selectInput('cat3', 'Choose car:', choices = sort(as.character(unique(df_subset1()$Car))), multiple = F, selected = NULL)
})
df_subset3 <- reactive({
if(is.null(input$cat4)){df_subset2()} else {df_subset2()[df_subset2()$Model %in% input$cat4,]}
})
output$category4 <- renderUI({
pickerInput('cat4', 'Choose model:', choices = sort(as.character(unique(df_subset2()$Model))), multiple = TRUE, selected = NULL)
})
output$plot <- renderPlotly({
xform <- list(categoryorder = "array",
categoryarray = df_subset3()$Month,
title = " ",
nticks=12)
plot_ly(data=df_subset3(), x=~Month, y = ~Value, type = 'scatter', mode = 'lines', name = 'Value') %>%
layout(title = " ",xaxis = xform) %>%
layout(legend = list(orientation = 'h', xanchor = "center", y=1.1, x=0.5))
})
}
shinyApp(ui, server)
To display each model as a separate line on the plot, you can assign the Model column of your dataset to the color parameter of plot_ly this way:
plot_ly( data = df_subset3(), x = ~Month, y = ~Value, color = ~Model, ...)
Error while geocoding addresses in my shiny app
I wish to upload a file in my shiny app and and then calculate latitude and longitude.Below is the code and here is the LINK(https://github.com/Pujaguptagithub/My_Data) to the dataset used.Please help as I am new to shiny.
library(shiny)
library(dplyr)
library(readxl)
library(sf)
library(mapsapi)
library(gsubfn)
library(pipeR)
ui <- fluidPage(
fileInput('csvFile', 'Choose xlsx file',
accept = c(".xlsx")),
tableOutput("rawData"),
tableOutput("modifiedData")
)
server <- function(input, output, session) {
rawData <- eventReactive(input$csvFile, {
read_excel(input$csvFile$datapath)
})
output$rawData <- renderTable({
rawData() %>% head
})
output$modifiedData <- renderTable({
rawData() %>% mutate(Locations = paste(as.character(rawData()$Address),
as.character(rawData()$City),as.character(rawData()$State),
as.character(rawData()$`Zip Code`), as.character(rawData()$Country),
sep=",")) %>%
mutate(aaa = gsub("NA;", "", Locations)) %>%
mutate(bbbb = mp_geocode(addresses = aaa, region = NULL, bounds = NULL,
key = "AIzaSyBQDna1fNBT5qeET39A0lp9nNEdezRLVyI")) %>%
mutate(ccc = mp_get_points(bbbb)) %>%
mutate(pnt = sub(ccc$pnt, pattern = "c", replacement = "")) %>%
mutate(eee = sub(pnt, pattern = "[(]", replacement = "")) %>%
mutate(ffff = sub(eee, pattern = "[)]", replacement = "")) %>%
mutate(gggg = sub(ffff, pattern = ",", replacement = "")) %>%
mutate(hhh = unlist(strsplit(gggg, split = " "))) %>%
mutate(Latitude = as.numeric(hhh[seq(2, length(hhh), 2)])) %>%
mutate(Longitude = as.numeric(hhh[seq(1, length(hhh), 2)]))
})
}
shinyApp(ui, server)
The below code works perfect outside the shiny :
Locations <- paste(Latlong$Address, Latlong$City,Latlong$State,Latlong$`Zip
Code`, Latlong$Country, sep=",")
Locations <- gsub("NA;", "", Locations)
Locations <- mp_geocode(addresses = Locations, region = NULL, bounds =
NULL, key = "AIzaSyBQDna1fNBT5qeET39A0lp9nNEdezRLVyI")
Locations = mp_get_points(Locations)
geom <- sub(Locations$pnt, pattern = "c", replacement = "")
geom <- sub(geom, pattern = "[(]", replacement = "")
geom <- sub(geom, pattern = "[)]", replacement = "")
geom <- sub(geom, pattern = ",", replacement = "")
lonlat <- unlist(strsplit(geom, split = " "))
Latlong$Latitude <- as.numeric(lonlat[seq(2, length(lonlat), 2)])
Latlong$Longitude <- as.numeric(lonlat[seq(1, length(lonlat), 2)])
check my entire app below, the only problem is due to line "df_svb <- Latlong", please help to get rid off the error.
library(shinyjs)
library(shinyWidgets)
library(shiny)
library(shinydashboard)
library(tidyverse)
library(devtools)
library(rsconnect)
library(readxl)
library(DT)
library(writexl)
library(stringi)
library(shinydashboardPlus)
library(ggmap)
library(zipcode)
library(leaflet)
library(htmltools)
library(data.table)
library(plotly)
library(mapsapi)
library(readxl)
Template <- read_excel("C:/Users/Template.xlsx")
header <- dashboardHeader(
# Set height of dashboardHeader
tags$li(class = "dropdown",
tags$style(".main-header .logo {height: 0px;}")),
title = div(img(src = 'svb_small.png',
style = "position:absolute; left:15px;
height: 80px;"))
)
##### Sidebar
sidebar <- dashboardSidebar(
shinyjs::useShinyjs(),
width = 400,
menuItem('Inputs',
id = 'side_panel',
#icon = icon("bar-chart-o"),
startExpanded = TRUE,
br(), br(),
fileInput('csvFile', 'Choose xlsx file',
accept = c(".xlsx")),
div(style = "font-size: 150%; font-family: sans-serif;",
selectizeGroupUI(
id = "my_filters",
params = list(
Country = list(inputId = "Country", title = "Country:"),
Company = list(inputId = "Company", title = "Company:")),
inline = FALSE)),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
downloadBttn('downloadData',
label = 'Download Template',
style = "gradient",
color = "primary"
)
)
)
body <- dashboardBody(
tags$style(type = "text/css", "#map_1 {height: calc(100vh - 80px)
!important;}"),
addSpinner(
leafletOutput("map_1"),
spin = 'folding-cube')
)
# Put them together into a dashboardPage
ui <- dashboardPage(header,sidebar,body, skin = "black")
options(shiny.maxRequestSize = 15*1024^2)
server <- function(input, output, session) {
rawData <- eventReactive(input$csvFile, {
read_excel(input$csvFile$datapath)
})
# Download template
output$downloadData <- downloadHandler(
filename = function() {"CBRE Geocoding and mapping Application.xlsx"},
content = function(file) {write_xlsx(Template, path = file)}
)
#SelectizeGroup function creates mutually dependent input filters
res_mod <- callModule(
module = selectizeGroupServer,
id = "my_filters",
data = df_svb,
vars = c('Country', 'Company')
)
modifiedData <- renderTable({
Latlong <- rawData()
Locations <- paste(Latlong$Address,
Latlong$City,Latlong$State,Latlong$`Zip Code`,
Latlong$Country, sep=",")
Locations <- gsub("NA;", "", Locations)
Locations <- mp_geocode(addresses = Locations, region = NULL, bounds=
NULL, key =
"AIzaSyBQDna1fNBT5qeET39A0lp9nNEdezRLVyI")
Locations = mp_get_points(Locations)
geom <- sub(Locations$pnt, pattern = "c", replacement = "")
geom <- sub(geom, pattern = "[(]", replacement = "")
geom <- sub(geom, pattern = "[)]", replacement = "")
geom <- sub(geom, pattern = ",", replacement = "")
lonlat <- unlist(strsplit(geom, split = " "))
Latlong$Latitude <- as.numeric(lonlat[seq(2, length(lonlat), 2)])
Latlong$Longitude <- as.numeric(lonlat[seq(1, length(lonlat), 2)])
Latlong
})
############################################################
df_svb <- Latlong
df_svb <- Latlong%>% mutate(
X = paste0('<font color="#006A4D">',
'<font-family: sans-serif>',
'<font size = "5">',
'<strong><font color="black">Country: </font color="black">
</strong>',
Country,
'<br><strong><font color="black">Company: </font color="black">
</strong>',
Company))
qpal <- colorFactor("BuPu", as.factor(df_svb$Company))
output$map_1 <- renderLeaflet(
leaflet(data = res_mod()) %>%
setView(-94.578568, 39.099728, zoom = 5) %>%
addProviderTiles(providers$Esri.WorldImagery, group = "Imagery Map") %>%
addProviderTiles(providers$Esri.WorldStreetMap, group = 'Street Map') %>%
addCircleMarkers(~Longitude, ~Latitude, group = 'svb',
fillColor = ~qpal(res_mod()$Company),
color = c("#006A4D","#FF0000"),
stroke = FALSE,
fillOpacity = 15,radius = 15,
labelOptions = labelOptions(noHide = T)
) %>%
addLayersControl(baseGroups = c('Street Map', "Imagery Map"),
options = layersControlOptions(collapsed = TRUE)) %>%
hideGroup('CBRE Locations') %>%
addLegend("topright", pal = qpal, values = ~res_mod()$Company,
title = "Company:", opacity = 1,group = 'svb' )
)
#Zooms in map when 1 office is chosen.
observe({
req(n_distinct(res_mod()$Country) == 1)
proxy <- leafletProxy('map_1')
proxy %>% setView(head(res_mod()$Longitude,1),
head(res_mod()$Latitude,1), zoom = 12)
})
}
shinyApp(ui, server)
UPDATE:
To add the data as a map, add this to the UI definition:
leafletOutput(outputId="myMap", height = 480)
And this will guide you on creating the server function:
output$myMap <- renderLeaflet({
# Test Data
#name <- c("London","Paris","Dublin")
#latitude <- c(51.5074,48.8566, 53.3498)
#longitude <- c(0.1278,2.3522, -6.2603)
#Latlong <- data.frame(name, latitude, longitude)
# Convert data frame to shape
coordinates(Latlong)<-~longitude+latitude
proj4string(Latlong)<- CRS("+proj=longlat +datum=WGS84")
shapeData <- spTransform(data,CRS("+proj=longlat"))
# Map the shape
map <- tm_shape(shapeData, name="Cities") +
tm_dots(size=0.2,title="Cities") +
tm_basemap("OpenStreetMap")+
tm_basemap("Esri.WorldImagery")
tmap_leaflet(map)
})
Original:
The issue seems to be in your call to the geocode function mp_get_points(). This is returning an xml document that can't be inserted into the new dataframe column ccc.
Is there any reason why you abandoned your original code? This seems to work fine if I insert it into your shiny app.
output$modifiedData <- renderTable({
Latlong <- rawData()
Locations <- paste(Latlong$Address, Latlong$City,Latlong$State,Latlong$`Zip
Code`, Latlong$Country, sep=",")
Locations <- gsub("NA;", "", Locations)
Locations <- mp_geocode(addresses = Locations, region = NULL, bounds =
NULL, key = "AIzaSyBQDna1fNBT5qeET39A0lp9nNEdezRLVyI")
Locations = mp_get_points(Locations)
geom <- sub(Locations$pnt, pattern = "c", replacement = "")
geom <- sub(geom, pattern = "[(]", replacement = "")
geom <- sub(geom, pattern = "[)]", replacement = "")
geom <- sub(geom, pattern = ",", replacement = "")
lonlat <- unlist(strsplit(geom, split = " "))
Latlong$Latitude <- as.numeric(lonlat[seq(2, length(lonlat), 2)])
Latlong$Longitude <- as.numeric(lonlat[seq(1, length(lonlat), 2)])
Latlong
})
I have been working on this shiny app for a while and it all seems to work till i get to the end. It is supposed to output a interactive scatter plot. Well I can get the plot to the point that it has a legend and the hover text pops up on a white blank background, but i am missing the visual points and the map. Outside of shiny i can make the plotly work just fine and i get my mapbox map and scatter plots. I have tired quite a few things but am still failing to render the points and the map. Is there a quark in shiny holding my map back from rendering with the points that i am missing here?
I also am getting this error that goes away when i remove the size or color function from my plot.
Error:
Warning: `line.width` does not currently support multiple values.
Ui:
library(readxl)
library(plyr)
library(dplyr)
library(plotly)
library(readr)
library(RColorBrewer)
library(data.table)
library(shiny)
library(shinydashboard)
library(shinythemes)
library(leaflet)
library(DT)
library(xtable)
ui <- fluidPage(theme = shinytheme("slate"), mainPanel(
navbarPage(
"Permian Plots", collapsible = TRUE, fluid = TRUE,
navbarMenu(
"County Plot",
tabPanel( "Data Frame",
fluidRow(box(DT::dataTableOutput("contents"))),
sidebarPanel( fileInput(
'file1',
'Choose CSV File',
accept = c('text/csv', 'text/comma-separated-values,text/plain', '.csv')
),
tags$hr(),
checkboxInput('header', 'Header', TRUE),
# App buttons comma and quote
radioButtons('sep', 'Separator',
c(
Comma = ',',
Semicolon = ';',
Tab = '\t'
), ','),
radioButtons(
'quote',
'Quote',
c(
None = '',
'Double Quote' = '"',
'Single Quote' = "'"
),
'"'
))
),
tabPanel("County Plot", plotlyOutput(
"plotMap", height = 1000, width = 1400
),
actionButton("btn", "Plot")
)
)
)
)
)
Server:
server <- function(input, output, session) {
options(shiny.maxRequestSize = 1000*1024^2)
data_set <- reactive({
inFile <- input$file1
if (is.null(inFile)){
return()
}
data_set <- read.csv(
inFile$datapath,
header = input$header,
sep = input$sep,
quote = input$quote
)
})
output$contents <- DT::renderDT({
withProgress(message = 'loading...', value = 0.1, {
datatab <- datatable(data_set(),
options = list(
"pageLength" = 10,
scrollX = TRUE))
extensions = 'Responsive'
setProgress(1)
datatab
})
})
observeEvent(
input$btn,
{
output$plotMap <- renderPlotly({withProgress(message = 'Plotting...', value = 0.1,{
plots <- function(f1){
f1 <- as.data.frame(f1)
f1$Date <- as.POSIXct(f1$Date)
f1$CNorm <- f1$Cell.Sum..Norm.
f1$year <- format(as.POSIXct(f1$Date,format="%y-%m-%d"), "%y")
f1$month <- format(as.POSIXct(f1$Date,format="%y-%m-%d"), "%m")
f1$Cell <- as.factor(f1$Cell)
z <- f1 %>%
group_by(.dots = c("year", "month", "Cell")) %>%
dplyr::summarise(yearMonth_Max_sum = max(CNorm))
f1 <- inner_join(f1,z, by = c("year", "month", "Cell"))
f1$Changed <- as.numeric(as.factor(f1$Changed))
f1$Changed[f1$Changed == 1] <- 0
f1$Changed[f1$Changed == 2] <- 1
z <- f1 %>%
group_by(.dots = c("year", "month", "Cell")) %>%
dplyr::summarise(ChangedX = max(Changed))
f1 <- inner_join(f1,z, by = c("year", "month", "Cell"))
f1$MY <- paste(f1$year, f1$month, sep = "-")
#preapring data for plotly
q <- matrix(quantile(f1$StdDev))
f1$qunat <- NA
up <- matrix(quantile(f1$StdDev, probs = .95))
f1$qunat <- ifelse((f1$StdDev > q[4:4,1]) & (f1$StdDev < up[1,1]), 1, 0)
z <- group_by(f1, Cell) %>%
dplyr::summarize(Median_Cell = median(CNorm), na.rm = FALSE)
f1 <- inner_join(f1,z, by = c("Cell"))
f1$NewMedian <- NA
f1$NewMedian[f1$Median_Cell > 4000] <- 0
f1$NewMedian[f1$Median_Cell <= 4000] <- 1
f1$NewSum <- NA
f1$NewSum <- f1$yearMonth_Max_sum * f1$ChangedX * f1$qunat * f1$NewMedian
f1$hover <- with(f1,paste("Sum", f1$yearMonth_Max_sum, "/<br>",
"Standard Dev", f1$StdDev, "/<br>",
"Mean", f1$Average, "/<br>",
"Median", f1$Median_Cell, "/<br>",
"Changed", f1$ChangedX, "/<br>",
"Latitude", f1$Lat , "/<br>",
"Longitude", f1$Lon))
f1 <- f1[which(f1$yearMonth_Max_sum < 9000), ]
f1 <<- f1[!duplicated(f1$yearMonth_Max_sum), ]
##################
Sys.setenv('MAPBOX_TOKEN' = '')
Sys.getenv("MAPBOX_TOKEN")
plot <- f1 %>%
plot_mapbox(
lon = ~Lon,
lat = ~Lat,
size = ~yearMonth_Max_sum,
color = ~NewSum,
frame = ~MY,
type = 'scattermapbox',
mode = "markers",
colors = c("green","blue")
) %>%
add_markers(text = ~f1$hover) %>%
layout(title = "County Plot",
font = list(color = "black"),
mapbox = list(style = "satellite-streets", zoom = 9,
center = list(lat = median(f1$Lat),
lon = median(f1$Lon))))
return(plot)
}
plots(data_set())
})
})
}
)
}
shinyApp(ui = ui, server = server)