如何在shinyapps.io部署的R ShinyApp中启用多区域设置?
我开发了一款支持生成英文、西班牙文、葡萄牙文报告的R Shiny应用,报告顶部的时间戳依赖Sys.setlocale和format函数,根据用户选择的语言正确翻译并显示日期(例如葡萄牙语显示“02 março, 2023”)。该功能在本地运行正常,但部署到shinyapps.io后,日志中出现以下警告:
OS reports request to set locale to "pt_BR.UTF-8" cannot be honored
OS reports request to set locale to "en_US.UTF-8" cannot be honored
简化后的app.R代码如下:
library(shiny) library(dplyr) library(tools) # cap functions ui <- fluidPage( selectInput( inputId="langSel", label="Select Language", choices=c("English"="en_US", "Spanish"="es_MX", "Portuguese"="pt_BR"), selected="en_US" ), textOutput("repDateOut") ) server <- function(input, output, session) { timeStamp <- "2023-03-02" # set locale depending on language selection to translate month observeEvent(input$langSel,{ Sys.setlocale("LC_TIME", paste0(input$langSel,".UTF-8")) }) repDate <- reactive({ dateOrder <- if (input$langSel=="en_US"){ '%B %d, %Y' # month before day for English } else { '%d %B, %Y' # day before month for everything else } fmDate <- format(as.Date(timeStamp), dateOrder) %>% {if (input$langSel=="en_US") toTitleCase(.) else .} # cap month for English only fmDate }) # print timestamp output$repDateOut <- renderText({repDate()}) } shinyApp(ui = ui, server = server)
尝试多种控制台部署命令后,每次仅最后指定的西班牙文区域设置生效,使用rsconnect.locale=c("en_US.UTF-8","pt_BR.UTF-8","es_MX.UTF-8")会导致部署报错:
尝试1:
options(rsconnect.locale.cache = FALSE, rsconnect.locale = "en_US.UTF-8") options(rsconnect.locale.cache = FALSE, rsconnect.locale = "pt_BR.UTF-8") options(rsconnect.locale.cache = FALSE, rsconnect.locale = "es_MX.UTF-8") rsconnect::deployApp()
尝试2:
options(rsconnect.locale.cache = FALSE, rsconnect.locale = "en_US.UTF-8") options(rsconnect.locale = "pt_BR.UTF-8") options(rsconnect.locale = "es_MX.UTF-8") rsconnect::deployApp()
尝试3:
options(rsconnect.locale.cache = FALSE, rsconnect.locale = "en_US.UTF-8", rsconnect.locale = "pt_BR.UTF-8", rsconnect.locale = "es_MX.UTF-8") rsconnect::deployApp()
请问如何让这三种区域设置在shinyapps.io中均可用?
shinyapps.io服务器默认未预装所有语言的locale包,Sys.setlocale切换locale的方式在云端环境无法生效,且rsconnect.locale参数仅支持单个locale值,无法同时指定多个。建议避开依赖系统locale的实现方式,改用以下两种方案:
方案1:手动定义多语言月份映射表
直接在代码中定义各语言对应的月份全称,通过日期提取月份索引匹配对应名称,再拼接成目标格式:
修改后的server代码:
server <- function(input, output, session) { timeStamp <- "2023-03-02" # 定义各语言的月份名称映射 month_names <- list( en_US = c("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), es_MX = c("enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"), pt_BR = c("janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro") ) repDate <- reactive({ date_obj <- as.Date(timeStamp) day_val <- format(date_obj, "%d") month_idx <- as.integer(format(date_obj, "%m")) year_val <- format(date_obj, "%Y") selected_month <- month_names[[input$langSel]][month_idx] if (input$langSel == "en_US") { paste0(selected_month, " ", day_val, ", ", year_val) } else { paste0(day_val, " ", selected_month, ", ", year_val) } }) output$repDateOut <- renderText({repDate()}) }
方案2:使用lubridate包的独立语言支持
lubridate提供了不依赖系统locale的日期格式化功能,通过locale参数直接指定语言:
首先加载lubridate包,再修改日期逻辑:
library(shiny) library(dplyr) library(lubridate) ui <- fluidPage( selectInput( inputId="langSel", label="Select Language", choices=c("English"="en_US", "Spanish"="es_MX", "Portuguese"="pt_BR"), selected="en_US" ), textOutput("repDateOut") ) server <- function(input, output, session) { timeStamp <- "2023-03-02" repDate <- reactive({ date_obj <- ymd(timeStamp) # 匹配lubridate支持的locale值 lang_locale <- switch(input$langSel, en_US = "en_US", es_MX = "es_ES", pt_BR = "pt_BR") if (input$langSel == "en_US") { format(date_obj, "%B %d, %Y", locale = lang_locale) } else { format(date_obj, "%d %B, %Y", locale = lang_locale) } }) output$repDateOut <- renderText({repDate()}) } shinyApp(ui = ui, server = server)
部署注意事项
- 无需设置
rsconnect.locale相关选项,直接执行rsconnect::deployApp()即可。 - 使用
lubridate时,需确保代码中明确加载该包,避免部署时缺失依赖。
内容的提问来源于stack exchange,提问作者bcarothers

