我有以下数据框:
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
为什么?
答案 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")