【问题标题】:Sorting formatted dates in R在R中对格式化日期进行排序
【发布时间】:2018-01-19 00:43:28
【问题描述】:

我在 R 中有一个日期和数值的数据框。日期都是一个月的第一天,并且值是与该月关联的数字

library(DT)
library(dplyr)
df <- data.frame(date = as.Date(c("2017-01-01","2017-02-01","2017-03-01","2017-04-01")), 
                 val = c(-5600,7000,4200,-2000))

我想通过DT::datatable() 坚持下去,这是我最喜欢的新事物。但是,我希望输出格式正确,千位分隔符,漂亮的日期等。

df <- df %>% mutate(val = formatC(val, big.mark=","))
datatable(df)

这会将val 转换为字符向量,尽管datatable() 显然能够识别它实际上是一个数字并使用标题中的箭头进行适当的排序。到目前为止一切顺利。

但是,当我尝试将日期格式化为 MMM YY 时,问题就出现了。

df <- df %>% mutate(date = format(date, "%b %y"))

datatable(df)

这也将日期转换为字符向量 - 值看起来像“Jan 17”等。一切看起来都很好,唯一的问题是当我按 date 排序时,它不会将值识别为月份并且将它们按字母顺序而非时间顺序排列。

有没有办法在将日期传递给datatable() 之前或同时重新格式化日期,以保持变量的“日期性”并允许对其进行适当排序?如果做不到这一点,是否还有另一个输出交互式表格并且更擅长排序的包?

提前致谢,

詹姆斯

【问题讨论】:

  • 我认为您应该避免更改数据列的类,而是构建一个您将在任何输出时使用的打印方法。

标签: r sorting date formatting


【解决方案1】:

您可以借助 lubridate 软件包。 并使用这个函数来做这些事情。

您需要做的是分别考虑月份和日期。

    library(lubridate)
date_conversion<-function(df){

  months<-month(df$date,label = T)
  years<-year(df$date)
  months_years<-paste(months, years, sep = " ")
  df[1]<-months_years
  df[order(row.names(df),decreasing = F),]

}

希望这对您有所帮助.... :)

【讨论】:

    【解决方案2】:

    DataTablesDT 包集成到 R 中,具有格式化数字和日期变量的选项,同时保持正确的排序顺序。

    下面,我将讨论三种不同的选择:

    library(DT)
    df <- data.frame(date = as.Date(c("2017-01-01","2017-02-01","2017-03-01","2017-04-01")), 
                     val = c(-5600,7000,4200,-12000))
    

    请注意,我故意选择更改val 列中的最后一个值,以证明使用formatC() 时存在缺陷。

    # OP's own formatting
    df$val_chr <- formatC(df$val, big.mark=",")
    df$date_chr <- format(df$date, "%b %y")
    # copy columns to demonstrate DT formatting
    df$val_dt <- df$val
    df$date_dt <- df$date
    # ISO 8601 year-month format as alternative
    df$dat_iso <- format(df$date, "%Y-%m")
    
    # create DT object and apply DT formatting
    datatable(df) %>%  formatCurrency("val_dt", "") %>% formatDate("date_dt", "toDateString")
    

    请注意,val_dt 的格式符合预期,并且正确对齐。相反,val_chr 左对齐,千位分隔符未对齐。此外,formatC() 已经识别出val 是 double 类型,并且默认使用了“g”格式。根据?formatCformat参数的描述默认为“d”表示整数,“g”表示实数。所以,我们确实得到了

        formatC(12000L, big.mark=",")
        #[1] "12,000"
    

    但是

        formatC(12000, big.mark=",")
        #[1] "1.2e+04"
    

    通过单击列标题右侧的小箭头符号在datatables 对象内按date_dt 排序,与date_chr 相比,可以正常工作。不幸的是,formatDate()is limited 的可用方法数量不包括所需的月-年格式。 (有一个datetime plugin,它将日期/时间源数据转换为适合显示的数据,但我没有详细探讨。)

    date_iso 列将abbreviated ISO 8601 format YYYY-MM 显示为第三个选项。这是我最喜欢的格式(我也经常使用它来按月汇总),因为

    • 即使好几年,它也总是能正确排序,
    • 它不依赖于当前的语言环境,因此它适用于任何语言,
    • 简短而明确,
    • 这是一个国际标准。

    附录

    formattable 包也确实有各种格式化功能,可以创建DataTables

    library(formattable)
    as.datatable(formattable(df))
    

    【讨论】:

    • 谢谢,formatDate 和它的亲戚看起来真的很有用,要是有更多的内置格式就好了!我会看一下插件,看看我在哪里。
    • datetime 插件似乎提供了不同的格式,但我还没有时间整合。如果你这样做,请发布作为答案!
    猜你喜欢
    • 2021-05-08
    • 2011-11-19
    • 2021-12-22
    • 2020-09-29
    • 1970-01-01
    • 2022-01-08
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多