You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 01:40:23