R - 如何将季度列转换为日期?

问题描述

我有一个包含“Period”(即四分之一)和“Percent”的 csv。将数据读入 R 后,“Period”列是“chr”,“Percent”列是“num”。我想将季度值更改为日期,因此:

for (i in 1:length(sloos_tighten$Period)) {
    sloos_tighten$Period[i] <- paste("Q",substring(sloos_tighten$Period[i],6),"/",1,4),sep = "")
    sloos_tighten$Period[i] <- as.Date(as.yearqtr(sloos_tighten$Period[i],format = "Q%q/%Y"))
} 

for 循环中的第一行将季度的格式更改为 as.yearqtr 可读,第二行将季度更改为日期。第一行按预期工作,但第二行将日期转换为四位数字。我认为这是因为“Period”的类型为“chr”,但我不知道如何将其更改为日期。我试图创建一个类型为日期的新列,但我找不到任何在线资源来解释它。任何帮助表示赞赏。提前致谢。

> dput(head(sloos_tighten,10))
structure(list(Period = c("1990:2","1990:3","1990:4","1991:1","1991:2","1991:3","1991:4","1992:1","1992:2","1992:3"),`Large and medium` = c(54.4,46.7,54.2,38.6,20,18.6,16.7,10,3.5,-3.4),Small = c(52.7,33.9,40.7,31.6,6.9,8.8,7,-7.1,-1.7)),row.names = c(NA,10L),class = "data.frame")

^导入后的数据是什么样子

解决方法

文字 for 循环在某种意义上很好,但不幸的是这里有两个问题:

  1. 这里有一个 class 问题:如果 $Period 是一个字符串,那么当你用 Date 类的东西重新分配它的一个值时,日期会被转换成字符串。这是因为在 R data.frame 中,除了少数例外,列中的所有值都必须是相同的类型。这是因为一列(几乎总是)是一个向量,而 R 将向量视为同质的。

    您可以通过预先分配 Date 类型的向量并对其进行零散分配来解决此问题:

    newdate <- rep(Sys.Date()[NA],nrow(sloos_tighten)) # just to get the class right
    for (i in 1:length(sloos_tighten$Period)) {
      tmp <- paste("Q",substring(sloos_tighten$Period[i],6),"/",1,4),sep = "")
      newdate[i] <- as.Date(as.yearqtr(tmp,format = "Q%q/%Y"))
    }
    

    (但是请不要使用这段代码,先看下面的#2。)

  2. 本身不是问题,而是效率:R 擅长将事情作为一个整体来处理。如果您一步重新分配所有 $Period,那么一切都会更快。

    sloos_tighten$Period <- 
      as.Date(
        paste0(substring(sloos_tighten$Period,substring(sloos_tighten$Period,4)),format = "%q/%Y")
    

    这从 paste(..,sep="") 切换到 paste0,这是一个方便的函数。然后,它删除了前导 "Q",因为我们实际上并没有保留它,所以为什么要添加它(除了可能是声明性代码)。最后,它一次处理整个字符串向量。

(这是将数据视而不见,因此未经测试。)