是否可以在 R Shiny 的“数据表”代码中格式化日期?

Is it possible to format Date in R Shiny "datatables" code?

提问人:Andrii 提问时间:11/11/2023 更新时间:11/12/2023 访问量:73

问:

我想在以 DT::d atatable 呈现表格时更改日期格式,具体取决于所选语言。假设“EN”的格式应为“yyyy-mm-dd”,FR的格式应为“dd-mm-yyyy”。

下面是代码片段的草图

library(DT)
library(data.table)

language <- "en"

df <- data.table(
  date = c("2023-11-09", "2023-11-10", "2023-11-11"),
  value = c(1, 2, 3))

# The format of "date" column should fit selected language
datatable(df) %>% formatDate(language)

欢迎任何关于如何以与“formatPercentage”或“formatCurrency”相同的方式做到这一点的想法,我们将不胜感激。

R 日期 DT

评论

1赞 Friede 11/11/2023
我们是从 接收所选语言,还是用户输入?在后一种情况下,我认为更难的任务是将用户插入的任何内容重新格式化为可用的格式。Sys.getlocale()
1赞 Andrii 11/11/2023
语言是根据已知用户的设置定义的。无需使用 getlocale。问题是要有类似“formatPercentage” - “formatDate”的东西,参数是“language”
1赞 Friede 11/11/2023
请详细说明语言标识符。例如,如果它是 en.wikipedia.org/wiki/ISO_3166-1(alpha-2 或 alpha-3),则可以在下表的帮助下完成: gist.github.com/mlconnor/1887156“2023-11-09”这是默认值/数据的初始存储方式?
0赞 Friede 11/12/2023
我试图给你一个起点。请看我改进的答案。

答:

1赞 Friede 11/12/2023 #1

我认为您需要根据查找表和您选择的国家/地区标识符编写自己的函数。

对于国家/地区代码(alpha-2 或 alpha-3),此派上用场。使用此表以及大多数日期重新格式化技术的想法是从 @Maël 的回答中借来的。

首先,我将这些想法包装在一个名为 .也许,有一些方法可以利用 .我还没有找到它们。formatDate2()DT::formatDate()

# v0.0.2
formatDate2 <- \(dt, language, warn = FALSE) {
  if(warn) 
    warning("Function is written for 'datatables'.\nRequires data column 'date' of class 'character', or 'Date'.")
  if(!any(attributes(dt)$class %in% c("datatables"))) 
    stop("Error: data object is no 'datatables'.")
  if(!("date" %in% names(dt$x$data))) 
    stop("Error: data column `date` is missing.")
  stopifnot(nchar(language) %in% c(2L, 3L))
  if(is.character(dt$x$data$date)) 
    dt$x$data$date <- as.Date(dt$x$data$date, "%Y-%m-%d") 
  ### --- borrowed from Mael --- ###
  lookup <- read.csv(
    "https://gist.githubusercontent.com/mlconnor/1887156/raw/014a026f00d0a0a1f5646a91780d26a90781a169/country_date_formats.csv")
  lookup$Date.Format <- 
    stringr::str_replace_all(string = lookup$Date.Format, 
                             pattern = c("yyyy" = "%Y", "MM" = "%m",
                                         "(?<!M|%)M(?!M)" = "%m", "dd" = "%d",
                                         "M" = "%M", "2555" = "%Y",
                                         "(?<!d|%)d(?!d)" = "%a"))
  ### ---   ################ --- ###
  if(nchar(language) == 2L) {
    if(!(language %in% lookup$ISO639.2.Country.Code)) 
      stop("Unknown country code.")
    f <- lookup[lookup$ISO639.2.Country.Code == language, "Date.Format"]
  } else {
    if(!(language %in% lookup$ISO.3166.Country.Code)) 
      stop("Unknown country code.")
    f <- lookup[lookup$ISO.3166.Country.Code == language, "Date.Format"]
  }
  dt$x$data$date <- format(x = dt$x$data$date, format = f)
  dt
}

您肯定必须进行更多的检查和一些修改。正如@Maël已经提到的,日期格式塑造w.r.t. 也应该改进。lookup$Date.Format

# your toy data 
library(DT)
library(data.table)
df <- data.table(
  date = c("2023-11-09", "2023-11-10", "2023-11-11"),
  value = c(1:3))
# testing 
df |> DT::datatable() |> formatDate2(language = "US") 
df |> DT::datatable() |> formatDate2(language = "DEU") 
df |> DT::datatable() |> formatDate2(language = "FR") 
df |> DT::datatable() |> formatDate2(language = "ABC") 

(德国)的结果:language = "DEU"

enter image description here

评论

0赞 Andrii 11/15/2023
我+1,但太复杂了