I'm trying to convert a data-frame column into date format. I'm using the zoo package, but can't get it to work. The desired output is either yyyy-mm-dd, so 4 dates per year.
This is what I've tried so far:
library(dplyr)
library(zoo)
as.yearqtr(1930, Q2)
as.yearqtr(1930, Q2, format = "%Y %Q%q")
To clarify. With the following code
as.yearqtr(1930, Q2, format = "%Y %Q%q") %>% as.Date()
The output is
[1] "1930-01-01"
which, of course, is the 1st quarter, but it should give "1930-03-01", i.e the second quarter.
CodePudding user response:
as.yearqtr takes a single character string or vector, not two. Always read the the help file first to find out what the arguments are. Below we show producing a yearqtr object. Internally yearqtr objects are represented by the year fraction where the fraction is 0, 1/4, 1/2, 3/4 for the 4 quarters respectively (so, for example, adding 1 gives the same quarter in the next year) and when displayed show as shown below.
library (zoo)
as.yearqtr(paste(1930, "Q2"))
## [1] "1930 Q2"
or
as.yearqtr(paste(1930, 2, sep = "-"))
## [1] "1930 Q2"
or
as.yearqtr(1930 (2 - 1)/4)
## [1] "1930 Q2"
To get a Date class object use as.Date on the above (or just use the above as is as it directly expresses a year and quarter).
as.Date(as.yearqtr(paste(1930, "Q2"))) # start of qtr
## [1] "1930-04-01"
as.Date(as.yearqtr(paste(1930, "Q2")), frac = 1) # end of qtr
## [1] "1930-06-30"
CodePudding user response:
Is this what you need?
library(zoo)
#>
#> Attaching package: 'zoo'
#> The following objects are masked from 'package:base':
#>
#> as.Date, as.Date.numeric
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
test = data.frame(year = rep(2000, 4),
qtr = paste0("Q", 1:4))
test |>
mutate(
qtr.num = case_when(
qtr == "Q1" ~ 0,
qtr == "Q2" ~ 0.25,
qtr == "Q3" ~ 0.5,
qtr == "Q4" ~ 0.75),
quarter = as.yearqtr(year qtr.num) |> as.Date())
#> year qtr qtr.num quarter
#> 1 2000 Q1 0.00 2000-01-01
#> 2 2000 Q2 0.25 2000-04-01
#> 3 2000 Q3 0.50 2000-07-01
#> 4 2000 Q4 0.75 2000-10-01
Created on 2023-01-20 with reprex v2.0.2
If you want a more simple solution, you may use the parse_date_time
function in lubridate
:
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
test = data.frame(year = rep(2000, 4),
qtr = paste0("Q", 1:4))
test |>
mutate(
quarter = parse_date_time(paste(year, qtr), orders="%Y %q"))
#> year qtr quarter
#> 1 2000 Q1 2000-01-01
#> 2 2000 Q2 2000-04-01
#> 3 2000 Q3 2000-07-01
#> 4 2000 Q4 2000-10-01
Created on 2023-01-20 with reprex v2.0.2