我是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命令,但似乎无法找到适当的代码。谁知道更好的方法呢?
答案 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
中执行此操作。使用grep
和cumsum
创建分组变量,从“日期”中提取数字子字符串,使用''
将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