I would like to floor a set of dates to the nearest decade, e.g:
1922 --> 1920,
2099 --> 2090,
etc.
I was hoping I could do this in Lubridate, as in:
floor_date(1922, 'decade')
But I get:
Error in match.arg(unit) :
'arg' should be one of “second”, “minute”, “hour”, “day”, “week”, “month”, “year”
Is there any way to do this gracefully, perhaps avoiding a bunch of if-else statement to do the binning, and hopefully avoiding a bunch of cut
s to do the grouping?
Floor a Year in R to nearest decade:
Think of Modulus as a way to extract the rightmost digit and use it to subtract from the original year. 1998 - 8 = 1990
> 1992 - 1992 %% 10
[1] 1990
> 1998 - 1998 %% 10
[1] 1990
Ceiling a Year in R to nearest decade:
Ceiling is exactly like floor, but add 10.
> 1998 - (1998 %% 10) + 10
[1] 2000
> 1992 - (1992 %% 10) + 10
[1] 2000
Round a Year in R to nearest decade:
Integer division converts your 1998 to 199.8, rounded to integer is 200, multiply that by 10 to get back to 2000.
> round(1992 / 10) * 10
[1] 1990
> round(1998 / 10) * 10
[1] 2000
floor_decade = function(value){ return(value - value %% 10) }
ceiling_decade = function(value){ return(floor_decade(value)+10) }
round_to_decade = function(value){ return(round(value / 10) * 10) }
print(floor_decade(1992))
print(floor_decade(1998))
print(ceiling_decade(1992))
print(ceiling_decade(1998))
print(round_to_decade(1992))
print(round_to_decade(1998))
which prints:
# 1990
# 1990
# 2000
# 2000
# 1990
# 2000
Source: https://rextester.com/AZL32693
Another way to round to nearest decade:
Neat trick with Rscript core function round
such that the second argument digits can take a negative number. See: https://www.rdocumentation.org/packages/base/versions/3.6.1/topics/Round
round(1992, -1) #prints 1990
round(1998, -1) #prints 2000
Don't be shy on the duct tape with this dob, it's the only thing holding the unit together.
You can just use some integer division here. Just see how many decades go into each number.
(c(1922, 2099) %/% 10) * 10
# [1] 1920 2090
You cannot use floor_date()
for integers; it is for date or datetime objects. As already suggested in MrFlick's answer, you don't need lubridate to do integer calculation. If you do want to use lubridate, it can be done something like this:
library(lubridate)
y <- ymd(c("2016-01-01", "2009-12-31"))
floor_date(y, years(10))
#> [1] "2010-01-01" "2000-01-01"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With