用 R 计算一年有多少天?
楚新元 / 2023-10-17
这个问题本质上就是判断给定年份是否为闰年,计算逻辑其实很简单:年份能被 4 整除、但不能被 100 整除,或能被 400 整除的年份为闰年,其余为平年;闰年 2 月份是 29 天,全年 366 年,平年 2 月份是 28 天,全年 365 天。我之所以会遇到这个问题是因为我在写 CNID 包的时候遇到了一个要判断身份证号码是否符合逻辑的问题。我写的代码有点啰嗦,感谢谢益辉亲自操刀在评论区给出了优雅、简洁且支持向量化的代码。
编写函数
# 判断闰年
leap_year = function(year) {
(year %% 4 == 0 & year %% 100 != 0) | (year %% 400 == 0)
}
# 计算一年有多少天
ydays = function(year) {
365 + leap_year(year)
}
# 计算某年某月有多少天
mdays = function(year, month) {
days = c(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[month]
days[month == 2 & leap_year(year)] = 29 # 闰年的二月为 29 天
days
}
# 年月组合
mdays_df = function(year, month) {
df = expand.grid(year = year, month = month)
cbind(df, days = do.call(mdays, as.list(df)))
}
实战测试
leap_year(2020:2024)
#> [1] TRUE FALSE FALSE FALSE TRUE
ydays(2020:2024)
#> [1] 366 365 365 365 366
mdays(2024, 1:12)
#> [1] 31 29 31 30 31 30 31 31 30 31 30 31
mdays_df(2020:2024, 1:4)
#> year month days
#> 1 2020 1 31
#> 2 2021 1 31
#> 3 2022 1 31
#> 4 2023 1 31
#> 5 2024 1 31
#> 6 2020 2 29
#> 7 2021 2 28
#> 8 2022 2 28
#> 9 2023 2 28
#> 10 2024 2 29
#> 11 2020 3 31
#> 12 2021 3 31
#> 13 2022 3 31
#> 14 2023 3 31
#> 15 2024 3 31
#> 16 2020 4 30
#> 17 2021 4 30
#> 18 2022 4 30
#> 19 2023 4 30
#> 20 2024 4 30