Floor a year to the decade in R

▼魔方 西西 提交于 2019-11-29 11:18:40

问题


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 cuts to do the grouping?


回答1:


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

Handy dandy copy pasta for those of you who don't like to think:

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

Don't be shy on the duct tape with this dob, it's the only thing holding the unit together.




回答2:


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



回答3:


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"



回答4:


You can also use the floor function like this:

floor(1922 / 10) * 10
# [1] 1920

If you need to round and not floor:

round(1922, digits = -1)
# [1] 1920


来源:https://stackoverflow.com/questions/35352914/floor-a-year-to-the-decade-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!