Hi All,
I am creating a Shiny App that populate 3 different figures for selected countries from my list. The app works locally on RStudio but I ran into this error (An error has occurred
The application failed to start.
exit status 1) upon deployment.
Please check out my app.R code:
library(shiny)
library(dplyr)
library(ggplot2)
library(scales)
library(tidyr)
library(stringr)
library(rsconnect)
# Example of loading the data (adjust this part to your data source)
data <- read.csv("TS_long.csv")
# Clean the country names (if necessary)
data$countrynewwb[data$countrynewwb == "Turkey"] <- "Türkiye"
data$countrynewwb[data$countrynewwb == "Cote d'Ivoire"] <- "Côte d’Ivoire"
# List of countries to prioritize
c_list <- c("Argentina", "Brazil", "India", "Malaysia", "South Africa", "Türkiye")
# UI Definition
ui <- fluidPage(
titlePanel("Findex Insights"),
sidebarLayout(
sidebarPanel(
selectInput("figure",
"Select Figure:",
choices = c("Account Ownership" = "account_ownership",
"Government Payments" = "gov_payments",
"Biggest Financial Worries" = "financial_worries")),
selectInput("countries",
"Select Countries:",
choices = c_list,
selected = NULL,
multiple = TRUE),
hr(),
helpText("Use the dropdowns to select a figure and countries.")
),
mainPanel(
uiOutput("dynamic_output") # Dynamic output based on figure selection
)
)
)
# Server Logic
server <- function(input, output, session) {
options(shiny.fullstacktrace = TRUE)
# Reactive data processing
selected_data <- reactive({
req(input$countries)
data %>%
filter(countrynewwb %in% input$countries) %>%
filter(group == "all") %>%
select(countrynewwb, year, ts_account, accfin_o_t, accmob_o_t, accboth_o_t) %>%
filter(!is.na(accfin_o_t)) %>%
na.omit() %>%
gather(group, value, accfin_o_t, accmob_o_t, accboth_o_t) %>%
mutate(total = ts_account * 100,
value = value * 100,
lab = ifelse(group == "accmob_o_t", round(total), NA)) %>%
filter(!is.na(total))
})
output$dynamic_output <- renderUI({
req(input$figure)
if (input$figure == "account_ownership") {
uiOutput("country_plots")
} else if (input$figure == "gov_payments") {
plotOutput("gov_payments")
} else if (input$figure == "financial_worries") {
plotOutput("financial_worries")
}
})
# Dynamically generate the plots for the selected countries
output$country_plots <- renderUI({
req(input$countries)
country_plots <- lapply(input$countries, function(country) {
plotOutput(outputId = paste0("plot_", country))
})
fluidRow(
do.call(tagList, country_plots)
)
})
# Render each individual plot for each selected country
observe({
req(input$countries) # Ensure that at least one country is selected
# Loop through the selected countries and create a plot for each
lapply(input$countries, function(country) {
output[[paste0("plot_", country)]] <- renderPlot({
data_1 <- selected_data() %>%
filter(countrynewwb == country) # Filter data for the current country
ggplot(data_1) +
geom_bar(aes(x = factor(year),
y = value,
fill = factor(group, levels = c("accmob_o_t", "accboth_o_t", "accfin_o_t"))),
stat = "identity",
position = "stack",
width = 0.75) +
scale_fill_manual(values = c("#15AFB7", "#5697D1", "#8066AC"),
breaks = c("accfin_o_t", "accboth_o_t", "accmob_o_t"),
labels = c("Financial institution account only",
"Financial institution account and mobile money account",
"Mobile money account only")) +
scale_y_continuous(limits = c(0, 100),
breaks = seq(0, 100, by = 20),
minor_breaks = seq(0, 100, by = 5)) +
geom_text(aes(x = factor(year),
y = total,
label = round(total)),
vjust = -0.5,
size = 5) +
facet_grid(.~factor(countrynewwb, levels = c_list),
scales = "free",
space = "free",
switch = "both",
labeller = label_wrap_gen(width = 10, multi_line = TRUE)) +
theme(
strip.placement = "outside",
strip.text.y.left = element_blank(),
strip.text.x = element_text(size = 16, family = "Nunito Sans", color = "black", angle = 0),
panel.background = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
panel.border = element_blank(),
legend.title = element_blank(),
legend.position = "bottom",
legend.justification = 'center',
legend.box.margin = margin(0, 0, 20, 0),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(family = "Nunito Sans", color = "black", angle = 0, size = 14, hjust = 1, vjust = 0.5),
legend.key.size = unit(4, "mm"),
axis.ticks.x = element_blank(),
axis.ticks.y = element_blank(),
plot.subtitle = element_text(size = 16, color = "black", family = "Nunito Sans"),
plot.title = element_text(hjust = 0, size = 16, color = "black", family = "Nunito Sans", face = "bold"),
plot.title.position = "plot",
legend.text = element_text(hjust = 0, size = 16, color = "black", family = "Nunito Sans"),
plot.caption = element_text(hjust = 0, size = 12, color = "black", family = "Nunito Sans"),
plot.caption.position = "plot") +
guides(fill = guide_legend(nrow = 3, byrow = TRUE)) +
labs(subtitle = "Adults with an account (%), 2011–21",
title = paste("Account ownership in", country))
})
})
})
output$gov_payments <- renderPlot({
req(input$countries)
data_g2p <- data %>%
filter(group == "all") %>%
select(countrynewwb, year, ts_g2p_MEdig, ts_g2p_MEcashonly, ts_g2p_MEother, ts_g2p_any) %>%
mutate(
method_digital = ts_g2p_MEdig,
method_cash_only = ts_g2p_MEcashonly,
method_other = ts_g2p_MEother,
total = ts_g2p_any
) %>%
gather(category, value, method_digital, method_cash_only, method_other) %>%
filter(year %in% c("2021", "2022", "2021/22")) %>%
filter(countrynewwb %in% input$countries) %>%
filter(!is.na(value)) %>%
group_by(countrynewwb, year) %>%
mutate(value = value * 100) %>%
mutate(
total = sum(value),
value_lab = ifelse(category == "method_digital", value, NA)
)
max_val <- max(data_g2p$total, na.rm = TRUE) + 7
if (max_val > 100) {
max_val <- 108
}
ggplot(data_g2p) +
geom_bar(aes(
x = countrynewwb,
y = value,
fill = category
),
stat = "identity",
position = "stack",
width = 0.75
) +
geom_text(aes(
x = countrynewwb,
y = total,
label = round(total)
),
vjust = -1,
size = 5
) +
geom_text(aes(
x = countrynewwb,
y = value,
fill = category,
label = round(value_lab, 0)
),
color = "white",
size = 5,
position = position_stack(vjust = 0.5)
) +
scale_fill_manual(
values = c("#15AFB7", "#F68E36", "#FBB615"),
labels = c(
"Digital payments",
"Cash-only payments",
"Other methods"
)
) +
scale_y_continuous(
limits = c(0, max_val),
breaks = seq(0, max_val, by = 20)
) +
theme_minimal() +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.x = element_text(size = 14, angle = 0),
axis.title.x = element_blank(),
axis.title.y = element_blank()
) +
labs(
title = "Government Payments",
subtitle = "Adults receiving government payments in the past year (%), 2021-2022"
)
})
### Biggest Financial Worries ###
selected_worry_data <- reactive({
req(input$countries)
data %>%
filter(group == "all") %>%
mutate(
gap1 = Mostworried_No,
gap2 = billmoney_M,
gap3 = oldmoney_M,
gap4 = schoolmoney_M,
gap5 = medmoney_M
) %>%
gather(group, value, gap1, gap2, gap3, gap4, gap5) %>%
mutate(value = value * 100) %>%
filter(countrynewwb %in% input$countries) %>%
filter(group %in% c("gap1", "gap2", "gap3", "gap4", "gap5")) %>%
filter(value > 0) # Exclude zero-value rows
})
output$financial_worries <- renderPlot({
req(input$countries)
worry_data <- selected_worry_data()
ggplot(worry_data, aes(x = factor(countrynewwb, levels = c_list), y = value)) +
geom_bar(
aes(
fill = factor(group, levels = c("gap1", "gap2", "gap3", "gap4", "gap5"))
),
stat = "identity",
position = "stack",
width = 0.75
) +
geom_text(
aes(
label = round(value, 0),
fill = group
),
color = "white",
size = 5,
position = position_stack(vjust = 0.5)
) +
scale_fill_manual(
values = c("#8066AC", "#69C9D0", "#15AFB7", "#F68E36", "#cccccc"),
labels = c(
"Medical expenses",
"School fees",
"Money for old age",
"Monthly expenses",
"Not worried"
)
) +
scale_y_continuous(
limits = c(0, 100),
breaks = seq(0, 100, by = 20)
) +
theme(
panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.ticks.x = element_blank(),
axis.text.x = element_text(size = 16, family = "Nunito Sans", color = "black"),
axis.text.y = element_blank(),
legend.position = "bottom",
legend.title = element_blank(),
legend.text = element_text(size = 16, family = "Nunito Sans"),
plot.subtitle = element_text(size = 16, family = "Nunito Sans"),
plot.title = element_text(size = 16, family = "Nunito Sans", face = "bold")
) +
labs(
subtitle = "Adults identifying their biggest financial worry (%), 2021",
title = "Biggest Financial Worry",
x = NULL,
y = NULL
) +
guides(fill = guide_legend(nrow = 2, byrow = TRUE))
})
}
# Run the application
shinyApp(ui = ui, server = server)
This app works on my RStudio, however, when I tried deploying, it gives this error on the Console:
Successfully deployed to https://apnguyen.shinyapps.io/test-figs/
Error in func(fname, ...) : app.R did not return a shiny.appobj object.
The app still runs at this point.
Here is my working logs from shinyapp
2025-01-14T16:14:00.964043+00:00 shinyapps[13708125]: Calls: local ... tryCatch -> tryCatchList -> tryCatchOne -> <Anonymous>
2025-01-14T16:14:00.969232+00:00 shinyapps[13708125]: Execution halted
2025-01-14T16:14:00.974778+00:00 shinyapps[13708125]: Shiny application exiting ...
2025-01-14T16:26:35.936524+00:00 shinyapps[13708125]: Running on host: a5f6e23036c3
2025-01-14T16:26:35.943922+00:00 shinyapps[13708125]: Running as user: uid=10001(shiny) gid=10001(shiny) groups=10001(shiny)
2025-01-14T16:26:35.949006+00:00 shinyapps[13708125]: Connect version: 2024.05.0
2025-01-14T16:26:35.955646+00:00 shinyapps[13708125]: LANG: C.UTF-8
2025-01-14T16:26:35.960533+00:00 shinyapps[13708125]: Working directory: /srv/connect/apps/test-figs
2025-01-14T16:26:35.965562+00:00 shinyapps[13708125]: Using R 4.4.1
2025-01-14T16:26:35.971172+00:00 shinyapps[13708125]: R.home(): /opt/R/4.4.1/lib/R
2025-01-14T16:26:35.976223+00:00 shinyapps[13708125]: Content will use current R environment
2025-01-14T16:26:35.982089+00:00 shinyapps[13708125]: R_LIBS: (unset)
2025-01-14T16:26:35.986891+00:00 shinyapps[13708125]: .libPaths(): /usr/lib/R, /opt/R/4.4.1/lib/R/library
2025-01-14T16:26:35.994090+00:00 shinyapps[13708125]: shiny version: 1.9.1
2025-01-14T16:26:35.999794+00:00 shinyapps[13708125]: httpuv version: 1.6.15
2025-01-14T16:26:36.004966+00:00 shinyapps[13708125]: rmarkdown version: (none)
2025-01-14T16:26:36.010651+00:00 shinyapps[13708125]: knitr version: (none)
2025-01-14T16:26:36.017003+00:00 shinyapps[13708125]: jsonlite version: 1.8.9
2025-01-14T16:26:36.021784+00:00 shinyapps[13708125]: RJSONIO version: (none)
2025-01-14T16:26:36.027158+00:00 shinyapps[13708125]: htmltools version: 0.5.8.1
2025-01-14T16:26:36.032375+00:00 shinyapps[13708125]: reticulate version: (none)
2025-01-14T16:26:36.037377+00:00 shinyapps[13708125]: Using pandoc: /opt/connect/ext/pandoc/2.16
2025-01-14T16:26:36.042699+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.048199+00:00 shinyapps[13708125]: Starting R with process ID: '246'
2025-01-14T16:26:36.053189+00:00 shinyapps[13708125]: Shiny application starting ...
2025-01-14T16:26:36.058119+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.062834+00:00 shinyapps[13708125]: Attaching package: ‘dplyr’
2025-01-14T16:26:36.068078+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.074352+00:00 shinyapps[13708125]: The following objects are masked from ‘package:stats’:
2025-01-14T16:26:36.079371+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.083981+00:00 shinyapps[13708125]: filter, lag
2025-01-14T16:26:36.088658+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.094420+00:00 shinyapps[13708125]: The following objects are masked from ‘package:base’:
2025-01-14T16:26:36.099655+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.104345+00:00 shinyapps[13708125]: intersect, setdiff, setequal, union
2025-01-14T16:26:36.110667+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.115405+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.120084+00:00 shinyapps[13708125]: Attaching package: ‘rsconnect’
2025-01-14T16:26:36.124759+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.129375+00:00 shinyapps[13708125]: The following object is masked from ‘package:shiny’:
2025-01-14T16:26:36.134243+00:00 shinyapps[13708125]:
2025-01-14T16:26:36.139731+00:00 shinyapps[13708125]: serverInfo
2025-01-14T16:26:36.145044+00:00 shinyapps[13708125]:
2025-01-14T16:26:39.956019+00:00 shinyapps[13708125]: ── Preparing for deployment ────────────────────────────────────────────────────
2025-01-14T16:26:39.961346+00:00 shinyapps[13708125]: Error in rsconnect::deployApp(account = "apnguyen") :
2025-01-14T16:26:39.967520+00:00 shinyapps[13708125]: No accounts registered.
2025-01-14T16:26:39.974000+00:00 shinyapps[13708125]: ℹ Call `rsconnect::setAccountInfo()` to register an account.
2025-01-14T16:26:39.981779+00:00 shinyapps[13708125]: Calls: local ... tryCatch -> tryCatchList -> tryCatchOne -> <Anonymous>
2025-01-14T16:26:39.987541+00:00 shinyapps[13708125]: Shiny application exiting ...
2025-01-14T16:26:39.992809+00:00 shinyapps[13708125]: Execution halted
I figured it was saying that my account was not registered here. I have since then verified my environment, checked for the account's registration (my account was listed), deleted my deployment records, re-registered and reconnected my account many times to the same error. And I still have an app that worked and successfully deployed using this account.