在R中生成季度日期的seq

时间:2016-05-27 02:07:28

标签: r date

我是R的新手,我的数据框看起来像这样。

 Date       A       B
1990 Q1     2       3
     Q2     4       2
     Q3     7       6
     Q4     5       3
1991 Q1     7       6
     Q2     1       8
     Q3     7       6
     Q4     9       2
1992 Q1     1       7
     Q2     4       6
     Q3     1       3
     Q4     5       8
...

该列一直延伸到行的末尾,并且由于数据不断更新,因此开始日期和结束日期都不固定。我想将日期列格式化为日期类,并实现如下:

 Date       A       B
1990 Q1     2       3
1990 Q2     4       2
1990 Q3     7       6
1990 Q4     5       3
1991 Q1     7       6
1991 Q2     1       8
1991 Q3     7       6
1991 Q4     9       2
1992 Q1     1       7
1992 Q2     4       6
1992 Q3     1       3
1992 Q4     5       8
...

我想在左边重新创建一个新的日期列,并使用数据提供的第一个日期(即' 1990 Q1')作为开始日期和基于行数的长度。正在看着使用seq。和as.yearqtr命令,但似乎无法找到适当的代码。谁知道更好的方法呢?

5 个答案:

答案 0 :(得分:1)

假设Date是单个字符列,这是使用tidyr的选项:

library(tidyr)

# separate date into year and quarter, inserting NAs in year as necessary
df %>% separate(Date, into = c('year', 'quarter'), fill = 'left') %>% 
    # fill NAs with previous value
    fill(year) %>% 
    # join year and quarter back into a single column
    unite(Date, year, quarter, sep = ' ')

#       Date A B
# 1  1990 Q1 2 3
# 2  1990 Q2 4 2
# 3  1990 Q3 7 6
# 4  1990 Q4 5 3
# 5  1991 Q1 7 6
# 6  1991 Q2 1 8
# 7  1991 Q3 7 6
# 8  1991 Q4 9 2
# 9  1992 Q1 1 7
# 10 1992 Q2 4 6
# 11 1992 Q3 1 3
# 12 1992 Q4 5 8

数据

df <- structure(list(Date = structure(c(1L, 4L, 5L, 6L, 2L, 4L, 5L, 
        6L, 3L, 4L, 5L, 6L), .Label = c("1990 Q1", "1991 Q1", "1992 Q1", 
        "Q2", "Q3", "Q4"), class = "factor"), A = c(2L, 4L, 7L, 5L, 7L, 
        1L, 7L, 9L, 1L, 4L, 1L, 5L), B = c(3L, 2L, 6L, 3L, 6L, 8L, 6L, 
        2L, 7L, 6L, 3L, 8L)), .Names = c("Date", "A", "B"), class = "data.frame", row.names = c(NA, 
        -12L))

答案 1 :(得分:1)

以下是创建您正在寻找的序列的直接方法:

numrows<-10  #number of elements desired

#create the sequence of Date objects
qtrseq<-seq(as.Date("1990-01-01"), by="quarter", length.out = numrows)

#created vector for the formatted display
qtrformatted<-paste(as.POSIXlt(myseq)$year+1900, quarters(myseq))

此方法和其他列出的解决方案的缺点是丢失了Date对象。在基础R中没有很好的方法来格式化Q1,Q2 ......并使对象保持为Date对象。根据您的应用程序,最好将日期序列存储在数据框中,并将该语句用于qtr格式化的输出目的。 祝你好运。

答案 2 :(得分:1)

我们可以在base R中执行此操作。使用grepcumsum创建分组变量,从“日期”中提取数字子字符串,使用''ave值替换为年份值,然后{{1使用paste提取季度子字符串。

sub

不需要Addtional包。

如果我们需要一个包解决方案,可以使用df$Date <- paste(ave(sub("\\s*Q.", "", df$Date), cumsum(grepl("^\\d+", df$Date)), FUN = function(x) x[nzchar(x)]), sub("^\\d+\\s+", "", df$Date)) df$Date #[1] "1990 Q1" "1990 Q2" "1990 Q3" "1990 Q4" "1991 Q1" "1991 Q2" #[7] "1991 Q3" "1991 Q4" "1992 Q1" "1992 Q2" "1992 Q3" "1992 Q4"

data.table

数据

library(data.table)
library(stringr)
setDT(df)[, Date:=sub("^(Q.*)", paste0(word(Date[1],1), " \\1") , Date), 
                                                 cumsum(grepl("^\\d+" , Date))]
df
#       Date A B
# 1: 1990 Q1 2 3
# 2: 1990 Q2 4 2
# 3: 1990 Q3 7 6
# 4: 1990 Q4 5 3
# 5: 1991 Q1 7 6
# 6: 1991 Q2 1 8
# 7: 1991 Q3 7 6
# 8: 1991 Q4 9 2
# 9: 1992 Q1 1 7
#10: 1992 Q2 4 6
#11: 1992 Q3 1 3
#12: 1992 Q4 5 8

答案 3 :(得分:1)

要使用yearqtr包中的zoo函数创建年度季度时间序列,您可以先将df$Date值拆分为年份和季度字符串,然后使用{{1同样来自na.locf包,使用上一行的值填充年份的缺失值,然后转换为具有年度季度日期的zoo时间序列。代码看起来像

zoo

答案 4 :(得分:0)

这是你可以尝试的东西

library(dplyr); library(stringr); library(zoo)
df %>% mutate(Date = paste(na.locf(str_extract(Date, "^[0-9]{4}")),     
                                   str_extract(Date, "Q[1-4]$"), sep = " "))
      Date A B
1  1990 Q1 2 3
2  1990 Q2 4 2
3  1990 Q3 7 6
4  1990 Q4 5 3
5  1991 Q1 7 6
6  1991 Q2 1 8
7  1991 Q3 7 6
8  1991 Q4 9 2
9  1992 Q1 1 7
10 1992 Q2 4 6
11 1992 Q3 1 3
12 1992 Q4 5 8