Hello,
I'm trying to deploy my shiny app to shinyapps.io.
I am getting the following error, even though it seems to have deployed successfully.
I do not have any install.packages()
call in my code. Another solution suggested by someone was to replace library()
with require()
. I did that and it still doesn't work.
This is my code:
# require(shiny)
require(shinyWidgets)
require(tidyr)
require(dplyr)
require(plotly)
require(mice)
require(DT)
options(scipen=999)
#-----------------------------------Data loading-----------------------------------
df <- read.csv("Housing_2020.csv")
#-----------------------------------Data cleaning and imputation-----------------------------------
df <- df[which(df$PROPERTY.TYPE == "Single Family Residential" | df$PROPERTY.TYPE == "Townhouse"), ]
mls <- c(14406995, 14414435, 14413706, 14414215, 14413861, 14410893, 14412244, 14410475, 14410950, 14409960, 14406098, 14409280, 14408549, 14409060, 14405753, 14404015, 14398327, 14402565, 14401776, 14401073, 14397227, 14398604, 14398183, 14397920, 14397210, 14396748, 14392264, 14376755, 14390655, 14390228, 14388336, 14389579, 14386430, 14386913, 14383999, 14385197, 14383280, 14380650, 14379630, 14360085, 14376802, 14375232, 14375867, 14334377, 61484, 61155, 14375675)
ls <- c(1559, 5983, 7667, 9705, 7344, 3099, 7658, 9026, 1680, 6721, 1202, 5001, 7500, 6111, 15246, 6775, 8089, 10498, 8015, 17860, 9579, 2914, 9583, 7491, 1891, 4530, 9772, 10001, 9418, 13068, 2439, 8206, 1620, 5022, 13068, 2239, 2605, 9592, 21780, 13068, 10402, 9757, 7479, 4295, 1786, 7187, 3429)
for(i in seq(1,length(mls))){
df[df$MLS. == mls[i], ]$LOT.SIZE <- ls[i]
}
df[df$MLS. == 14384584, ]$BATHS <- 3
df[df$MLS. == 61484, ]$YEAR.BUILT <- 2006
df[df$MLS. == 61155, ]$YEAR.BUILT <- 1998
#-----------------------------------MICE-----------------------------------
# Application loading take a little longer as imputation needs to be performed.
df1 <- df %>% select(BEDS, BATHS, SQUARE.FEET, LOT.SIZE, YEAR.BUILT, PRICE)
my_imp <- mice(df1, method = c("","","","rf","",""), seed = 0, printFlag = TRUE) #Imputation performed on LOT.SIZE column
df1 <- complete(my_imp)
#-----------------------------------APP-----------------------------------
ui <- fluidPage(
tabsetPanel(
tabPanel("Tab 1",
titlePanel("Histogram of Price by ZIP Code"),
sidebarLayout(
sidebarPanel(selectInput(inputId = "zip", label = "Select ZIP Code", c(Choose = "", df$ZIP.OR.POSTAL.CODE) , selected = 75080, multiple = TRUE)),
mainPanel(plotOutput(outputId = "histogram"), textOutput(outputId = "text"))
)),
tabPanel("Tab 2",
titlePanel("Median Property Prices by ZIP Code"),
dataTableOutput("mytable")),
tabPanel("Tab 3",
titlePanel("Boxplot of Prices"),
sidebarLayout(
sidebarPanel(
sliderTextInput(inputId = "beds",
label = "Beds:",
choices = sort(unique(df$BEDS, na.rm = TRUE)),
grid = TRUE,
selected = c(min(sort(unique(df$BEDS, na.rm = TRUE))),max(sort(unique(df$BEDS, na.rm = TRUE))))),
sliderTextInput(inputId = "baths",
label = "Baths:",
choices = sort(unique(df$BATHS, na.rm = TRUE)),
grid = TRUE,
selected = c(min(sort(unique(df$BATHS, na.rm = TRUE))),max(sort(unique(df$BATHS, na.rm = TRUE))))),
sliderTextInput(inputId = "squarefeet",
label = "Square Feet:",
choices = sort(unique(df$SQUARE.FEET, na.rm = TRUE)),
grid = TRUE,
selected = c(min(sort(unique(df$SQUARE.FEET, na.rm = TRUE))),max(sort(unique(df$SQUARE.FEET, na.rm = TRUE))))),
sliderTextInput(inputId = "lotsize",
label = "Lot Size:",
choices = sort(unique(df$LOT.SIZE, na.rm = TRUE)),
grid = TRUE,
selected = c(min(sort(unique(df$LOT.SIZE, na.rm = TRUE))),max(sort(unique(df$LOT.SIZE, na.rm = TRUE))))),
sliderTextInput(inputId = "yearbuilt",
label = "Year Built:",
choices = sort(unique(df$YEAR.BUILT, na.rm = TRUE)),
grid = TRUE,
selected = c(min(sort(unique(df$YEAR.BUILT, na.rm = TRUE))),max(sort(unique(df$YEAR.BUILT, na.rm = TRUE)))))
),
mainPanel(
plotlyOutput(outputId = "boxplot"),
br(),
textOutput(outputId = "text1"),
textOutput(outputId = "text2"),
)
)
),
tabPanel("Tab 4",
plotlyOutput(outputId = "map", height = '900px'))
)
)
server <- function(input, output){
#TAB 1
# If the input field is empty, histogram for all the prices is displayed. Otherwise, histogram is displayed only for selected zip code(s).
# Bin width taken as $50,000.
# Default zip code is 75080.
output$text <- renderText("Dashed blue line indicates median")
output$histogram <- renderPlot(if (is.null(input$zip)){
ggplot(df, aes(x=PRICE)) + geom_histogram(binwidth = 50000, color = "darkblue", fill = "lightblue") +
theme_classic() +
labs(title="Histogram Plot",x="Price($)", y = "Count") +
geom_vline(aes(xintercept=median(PRICE)),color="blue", linetype="dashed", size=1)
} else{
ggplot(df[df$ZIP.OR.POSTAL.CODE == input$zip, ], aes(x=PRICE)) +
geom_histogram(binwidth = 50000, color = "darkblue", fill = "lightblue") +
theme_classic() +
labs(title="Histogram Plot",x="Price($)", y = "Count") +
geom_vline(aes(xintercept=median(PRICE)),color="blue", linetype="dashed", size=1)
})
#TAB 2
# Pivot table created using pivot_wider(). Median price has been used to populate each cell (values_fn).
widedf <- pivot_wider(df, id_cols = c(ZIP.OR.POSTAL.CODE), names_from = PROPERTY.TYPE, values_from = PRICE, values_fn = median)
widedf <- widedf[order(-widedf$`Single Family Residential`),]
names(widedf) <- c("ZIP", "Single Family Residential", "Townhouse")
output$mytable = renderDataTable(datatable(widedf) %>% formatCurrency(2:3,'$'))
#TAB 3
# Plotly's boxplot has been used as it provides interactive features like zooming in.
output$text1 <- renderText(
paste("Beds:", paste(input$beds, collapse = "-"), ", Baths:", paste(input$baths, collapse = "-"), ", Square Feet:", paste(input$squarefeet, collapse = "-"), ", Lot Size:", paste(input$lotsize, collapse = "-"), ", Year Built:", paste(input$yearbuilt, collapse = "-"))
) # Displays the selected ranges for each variable
output$text2 <- renderText("Values selected in the range slider are inclusive.")
output$boxplot <- renderPlotly(
plot_ly(x = "", y = df1[df1$BEDS >= input$beds[1] & df1$BEDS <= input$beds[2] & df1$BATHS >= input$baths[1] & df1$BATHS <= input$baths[2] & df1$SQUARE.FEET >= input$squarefeet[1] & df1$SQUARE.FEET <= input$squarefeet[2] & df1$LOT.SIZE >= input$lotsize[1] & df1$LOT.SIZE <= input$lotsize[2] & df1$YEAR.BUILT >= input$yearbuilt[1] & df1$YEAR.BUILT <= input$yearbuilt[2], ]$PRICE, type = "box", jitter = 0.9)
%>% layout(yaxis = list(title = "PRICE ($)"))
)
#TAB 4
# Leaflet used, however, map rendering times were too long and application would crash. Plotly renders all the ~4000 points smoothly.
Sys.setenv('MAPBOX_TOKEN' = NA) # Token needed for certain vector maps
fig <- df %>% plot_mapbox(lat = ~LATITUDE,
lon = ~LONGITUDE,
split = ~PROPERTY.TYPE,
size=2,
mode = 'scattermapbox',
hoverinfo='text',
hovertext = paste("<b>Price($):</b>", df$PRICE, "<br>", "<b>Property Type:</b>", df$PROPERTY.TYPE, "<br>", "<b>Square Feet:</b>", df$SQUARE.FEET, "<br>", "<b>Beds:</b>", df$BEDS, "<br>", "<b>Baths:</b>", df$BATHS, "<br>", "<b>MLS#:</b>", df$MLS., "<br>", "<b>City:</b>", df$CITY)
)
fig <- fig %>% layout(title = 'Housing Map',
font = list(color='white'),
plot_bgcolor = '#191A1A',
paper_bgcolor = '#000000',
mapbox = list(style = "open-street-map",
zoom = 8.5,
center = list(lat = ~mean(LATITUDE), lon = ~mean(LONGITUDE))),
legend = list(orientation = 'v',
font = list(size = 12)),
margin = list(l = 30, r = 30,
b = 30, t = 30,
pad = 2))
output$map <- renderPlotly(fig)
}
shinyApp(ui = ui, server = server)