格式化日期为年/季

时间:2014-02-05 08:05:00

标签: r date

我有以下数据框:

Data <- data.frame(
  date = c("2001-01-01", "2001-02-01", "2001-03-01", "2001-04-01", "2001-05-01", "2001-06-01"),
  qtr = c("NA", "NA","NA","NA","NA","NA")
)

我想用Year / Quater填充Data $ qtr - f.e. 01/01(我需要这种格式!)。

我写了一个函数:

fun <- function(x) { 
  if(x == "2001-01-01" | x == "2001-02-01" | x == "2001-03-01") y <- "01/01"
  if(x == "2001-04-01" | x == "2001-05-01" | x == "2001-06-01") y <- "01/02"
  return(y)
}
n$qtr <- sapply(n$date, fun)

但它不起作用。我总是收到错误消息:

Error in FUN(X[[1L]], ...) : Object 'y' not found

为什么?

9 个答案:

答案 0 :(得分:27)

你需要明确Vectorize你的职能:

fun_v <- Vectorize(fun, "x")
fun_v(Data$date)
#[1] "01/01" "01/01" "01/01" "01/02" "01/02" "01/02"

然而,当谈到或多或少的标准任务(例如日期时间操作)时,总有一个解决方案已经可用:

library(zoo)
yq <- as.yearqtr(Data$date, format = "%Y-%m-%d")
yq
#[1] "2001 Q1" "2001 Q1" "2001 Q1" "2001 Q2" "2001 Q2" "2001 Q2"

要转换为您的特定格式,请使用

format(yq, format = "%y/0%q")
#[1] "01/01" "01/01" "01/01" "01/02" "01/02" "01/02"

答案 1 :(得分:10)

使用基本功能:

Data$date <- as.Date(Data$date)
Data$qtr <- paste(format(Data$date, "%y"), 
                  sprintf("%02i", (as.POSIXlt(Data$date)$mon) %/% 3L + 1L), 
                  sep="/")

#         date   qtr
# 1 2001-01-01 01/01
# 2 2001-02-01 01/01
# 3 2001-03-01 01/01
# 4 2001-04-01 01/02
# 5 2001-05-01 01/02
# 6 2001-06-01 01/02

答案 2 :(得分:4)

我一直喜欢使用lubridate套餐来处理日期。超级光滑。 quarter函数找到季度(当然),然后将其与年份配对。

library(lubridate)
Data <- Data %>%
  mutate(qtr = paste0(substring(year(date),2,4),"/0",quarter(date))) 

如果您不熟悉%>%第一行基本上说“使用名为data的数据框”,第二行说“改变(或添加)名为qtr的列“

答案 3 :(得分:2)

我使用R:

中的quarters()和sub()制作了类似的格式
  Data$qtr <- paste(format(Data$date, "%y/"), 0, 
              sub( "Q", "", quarters(Data$date) ), sep = "")

希望这有帮助!

答案 4 :(得分:2)

另一个选择是:

Data$qtr <- lubridate::quarter(Data$date, with_year = T)

答案 5 :(得分:0)

另一种(更长的)方式  使用if语句这样做:

month <- as.numeric(format(date, format = "%m"))[1]

if (month < 4) {
    quarter <- paste( format(date, format = "%Y")[1], "Q1", sep="-")
} else if (month > 3 & month < 7) {
    quarter <- paste( format(date, format = "%Y")[1], "Q2", sep="-")            
} else if (month > 6 & month < 10) {
    quarter <- paste( format(date, format = "%Y")[1], "Q3", sep="-")
} else if (month > 9) {
    quarter <- paste( format(date, format = "%Y")[1], "Q4", sep="-")
}

返回格式为

的字符串
> quarter
[1] "2001-Q1"

然后你可以使用循环扩展它。

答案 6 :(得分:0)

yq=function(x,prefix="%Y",combine="Q") paste0(ifelse(is.null(prefix),"",format(x,"%Y")),floor(as.numeric(format(x,"%m"))/3-1e-3)+1,sep=combine)

这样可以灵活地返回任何具有季度的格式

不需要chron或动物园

至于你的例子

yq(as.Date("2013-04-30"),prefix="%y",combine="/0")
> [1] "13/02"

答案 7 :(得分:0)

data.table软件包及其IDate类具有一些不错的便捷功能(例如quarter()year()),类似于可用的lubridate。根据需要将它们paste0()在一起。

Data <- data.frame(
  date = c("2001-01-01", "2001-02-01", "2001-03-01",
           "2001-04-01", "2001-05-01", "2001-06-01")
)

require(data.table)
setDT(Data)

Data[ , date := as.IDate(date) ] # data.table s integer based date class
Data[ , qtr := paste0(year(date), '/', quarter(date)) ]
# your specific format
Data[ , qt2 := paste0(substr(year(date),3,4),
                      '/',
                      paste0('0', quarter(date))) ]

答案 8 :(得分:0)

如果有人正在寻找 21 年第一季度的 1Q21 之类的格式,我使用上面的@Roland 回答并做了一个小改动:

paste(sprintf("%2i", (as.POSIXlt(Notional$Date)$mon) %/% 3L + 1L), format(Notional$Date, "%y"),sep="Q")