Extract only quarter from a date in r
I would do:
# example data
DT = data.table(id = 1:10, d = as.IDate("2003-02-08") + seq(100, by=50, length.out=10))
DT[, qtr := quarter(d)]
id d qtr
1: 1 2003-05-19 2
2: 2 2003-07-08 3
3: 3 2003-08-27 3
4: 4 2003-10-16 4
5: 5 2003-12-05 4
6: 6 2004-01-24 1
7: 7 2004-03-14 1
8: 8 2004-05-03 2
9: 9 2004-06-22 2
10: 10 2004-08-11 3
The quarter
function is provided by data.table and works on both Date
and IDate
vectors. (IDate
uses integer storage.)
Format date as Year/Quarter
You need to explicilty Vectorize
your function:
fun_v <- Vectorize(fun, "x")
fun_v(Data$date)
#[1] "01/01" "01/01" "01/01" "01/02" "01/02" "01/02"
However, when it comes to more or less standard tasks (such as datetime manipulations), there's always a solution already available:
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"
To convert to your specific format, use
format(yq, format = "%y/0%q")
#[1] "01/01" "01/01" "01/01" "01/02" "01/02" "01/02"
How to get every quarter of a date interval in R?
If df
is your data frame, what the following does is generate the sequence of all months from startdate to enddate, retain unique combinations of product and quarters and calculate the average.
library(lubridate)
library(dplyr)
df <- df %>%
mutate(startdate = ymd(startdate),
enddate = ymd(enddate))
df$output <- mapply(function(x,y) seq(x, y, by = "month"),
df$startdate,
df$enddate)
df %>%
tidyr::unnest(output) %>%
mutate(quarter = paste0("Q",quarter(output), " ", year(output))) %>%
select(-output) %>%
group_by(product, startdate, enddate, quarter) %>%
filter(row_number(quarter) == 1) %>%
summarise(mean(price))
Result for the first row of your data frame would be:
product startdate enddate quarter `mean(price)`
<int> <date> <date> <chr> <dbl>
1 1 2012-03-17 2016-09-08 Q1 2012 10
2 1 2012-03-17 2016-09-08 Q1 2013 10
3 1 2012-03-17 2016-09-08 Q1 2014 10
4 1 2012-03-17 2016-09-08 Q1 2015 10
5 1 2012-03-17 2016-09-08 Q1 2016 10
6 1 2012-03-17 2016-09-08 Q2 2012 10
7 1 2012-03-17 2016-09-08 Q2 2013 10
8 1 2012-03-17 2016-09-08 Q2 2014 10
9 1 2012-03-17 2016-09-08 Q2 2015 10
10 1 2012-03-17 2016-09-08 Q2 2016 10
11 1 2012-03-17 2016-09-08 Q3 2012 10
12 1 2012-03-17 2016-09-08 Q3 2013 10
13 1 2012-03-17 2016-09-08 Q3 2014 10
14 1 2012-03-17 2016-09-08 Q3 2015 10
15 1 2012-03-17 2016-09-08 Q3 2016 10
16 1 2012-03-17 2016-09-08 Q4 2012 10
17 1 2012-03-17 2016-09-08 Q4 2013 10
18 1 2012-03-17 2016-09-08 Q4 2014 10
19 1 2012-03-17 2016-09-08 Q4 2015 10
Create a vector of year/quarters from a starting date
Convert the input x to yearqtr class. It represents year and quarter internally as year + 0, 1/4, 1/2 and 3/4 so just add whatever number of quarters needed. It renders them as shown. See ?yearqtr
for more info.
library(zoo)
x <- "2021 Q3"
as.yearqtr(x) + seq(0, length = 5) / 4
## [1] "2021 Q3" "2021 Q4" "2022 Q1" "2022 Q2" "2022 Q3"
Convert date field to Quarter in R
The zoo library has created a set of functions to handle year-quarter vectors:
library(zoo)
mydf$var9=as.yearqtr(as.Date( mydf$Order.Date, "%m/%d/%Y" ).
Get beginning of next quarter from current Date in R
1) zoo Convert to "yearqtr"
class, add 1/4 and if you want the date at the end of the quarter apply as.Date
using frac = 1
library(zoo)
today <- Sys.Date() # 2016-01-27
as.Date(as.yearqtr(today) + 1/4, frac = 1)
## [1] "2016-06-30"
Omit frac=1
if you want the start of the quarter. Omit as.Date
if you want the "yearqtr"
object:
as.yearqtr(today) + 1/4
[1] "2016 Q2"
2) base of R. This will give the beginning date of the next quarter with no packages. We use cut
to get the beginning of the current quarter, convert to "Date"
class and add enough days to get to the next quarter and apply cut
and as.Date
again:
as.Date(cut(as.Date(cut(today, "quarter")) + 100, "quarter"))
## [1] "2016-04-01"
If you want the end of the quarter add enough days to get to the second next quarter and subtact 1 day to get to the end of the prior quarter:
as.Date(cut(as.Date(cut(today, "quarter")) + 200, "quarter")) - 1
## [1] "2016-06-30"
Convert character field to quarter date in R
If you insist on using the base R as.Date()
function, then one option for you to consider is mapping the quarters to months. In the below code, I map the quarter to the first month occurring in that quarter. Then I tag on "01"
for the first day in that month, and afterward convert to a date.
trim <- c("1992-4", "1993-1")
trim <- gsub("-1", "-01", trim) # map first quarter to January
trim <- gsub("-2", "-04", trim) # map second quarter to April
trim <- gsub("-3", "-07", trim) # map third quarter to July
trim <- gsub("-4", "-10", trim) # map fourth quarter October
trim <- paste(trim, "-01", sep="") # add first day of the month
trim <- as.Date(trim, "%Y-%m-%d") # convert to date
> trim
[1] "1992-10-01" "1993-01-01"
P.S. This question is sort of a duplicate of this SO post. But it's different enough to merit a new answer IMO.
Get last day in quarter
Here's just one way
library(dplyr)
library(lubridate)
dat %>%
group_by(quarter=quarter(date, T)) %>%
filter(date==max(date)) %>%
ungroup %>%
select(-quarter)
# # A tibble: 7 x 2
# date value
# <date> <dbl>
# 1 2015-03-31 90
# 2 2015-06-30 181
# 3 2015-09-30 273
# 4 2015-12-31 365
# 5 2016-03-31 456
# 6 2016-06-30 547
# 7 2016-08-01 579
Related Topics
How to Edit Column Names in Datatable Function When Running R Shiny App
Plot a Function with Several Arguments in R
Geom_Bar + Geom_Line: with Different Y-Axis Scale
Dist Function with Large Number of Points
Cannot Install Stringi Since Xcode Command Line Tools Update
Combining .Sd with Renamed Variable Messes with Names of .Sd Columns
Create a New Column with Non-Null Columns' Names
Understanding Bandwidth Smoothing in Ggplot2
Counting the Number of Values Greater Than 0 in R in Multiple Columns
Function for Polynomials of Arbitrary Order (Symbolic Method Preferred)
Calculate Difference Between Dates by Group in R
How to Format the X-Axis of the Hard Coded Plotting Function of Spei Package in R