R 语言|时间与季节的转换:注意区分南北半球

文摘   2024-11-12 10:55   江苏  
  • 1 引言

  • 2 一些日期

  • 3 备注

  • 4 函数 1

  • 5 函数 2

  • 6 函数 3

  • 7 函数 4

  • 8 应用函数

  • 9 检查是否一致

  • 10 现成包里的函数

1 引言

在最近 Nature 的一篇观点文章中,作者指出,学术交流中频繁使用的“季节”(Season)这个(单)词,可能带有潜在的欧美中心倾向。

它带来的问题在全球性研究中更为明显:部分研人员甚至把 6、7、8 月直接视为全球的“夏季”,忽视了南北半球的季节差异。这种“疏忽”直接影响了分析的准确性。因此,在提到“季节”时,明确“半球”尤为重要。

为了正确地处理不同半球的季节转换,我们可以尝试编写自定义函数(见后文编写的 4 个函数),将日期根据所在半球转换为对应的季节。尽管已有部分 R 包提供了季节转换功能,但普遍缺乏对南北半球的考量。

2 一些日期

# 一些日期 ----
# __________
some_dates <- as.Date(
c(
"2020-08-13", "2020-01-11", "2020-04-03",
"2020-06-30", "2020-11-25", "2020-02-07"
)
)
class(some_dates)
[1] "Date"

3 备注

  • 北半球:3-5 月为春季,6-8 月为夏季,9-11 月为秋季,12-2 月为冬季。

  • 南半球:3-5 月为秋季,6-8 月为冬季,9-11 月为春季,12-2 月为夏季。

4 函数 1

根据月份数字,判断季节。

# 函数 1 ----
# __________
date2season1 <- function(dates, hemisphere = "north") {
months <- as.integer(format(dates, "%m"))
seasons <- sapply(months, function(month) {
# 计算南半球的月份:由于南半球的季节与北半球相反,
# 我们通过将月份加上 6 再对 12 取余数(保证结果在 1 到 12 之间)来调整月份,
# 这样可以将北半球的春季(3 月到 5 月)映射到南半球的秋季(9 月到 11 月),
# 夏季(6 月到 8 月)映射到冬季(12 月到 2 月),以此类推。
if (hemisphere == "south") {
month <- (month + 6 - 1) %% 12 + 1
}

# 根据月份判断季节:使用调整后的月份来确定季节,
# 3 月到 5 月为春季,6 月到 8 月为夏季,9 月到 11 月为秋季,其余月份为冬季。
# if (month >= 3 && month <= 5) {
# "Spring"
# } else if (month >= 6 && month <= 8) {
# "Summer"
# } else if (month >= 9 && month <= 11) {
# "Autumn"
# } else {
# "Winter"
# }

# 或者使用 %in% 匹配符号。
if (month %in% 3:5) {
return("Spring")
} else if (month %in% 6:8) {
return("Summer")
} else if (month %in% 9:11) {
return("Autumn")
} else {
return("Winter")
}
})
return(seasons)
}

5 函数 2

使用一个预定义的季节映射表,减少条件判断。

# 函数 2 ----
# __________
# 使用一个预定义的季节映射表,
# 减少条件判断。
date2season2 <- function(dates, hemisphere = "north") {
# 定义季节的映射表
seasons_north <- c(
rep("Winter", 2),
rep("Spring", 3),
rep("Summer", 3),
rep("Autumn", 3),
"Winter"
)
seasons_south <- c(
rep("Summer", 2),
rep("Autumn", 3),
rep("Winter", 3),
rep("Spring", 3),
"Summer"
)

# 根据月份查找对应季节
months <- as.integer(format(dates, "%m"))
if (hemisphere == "north") {
seasons <- seasons_north[months]
} else {
seasons <- seasons_south[months]
}

return(seasons)
}

6 函数 3

保留月份平移的方式,直接计算转换后的季节,而不需要单独的判断逻辑。

# 函数 3 ----
# __________
# 如果坚持保留月份平移的方式,
# 可以直接计算转换后的季节,
# 而不需要单独的判断逻辑。
date2season3 <- function(dates, hemisphere = "north") {
months <- as.integer(format(dates, "%m"))

# 如果是南半球,将月份偏移 6
if (hemisphere == "south") {
months <- (months + 6 - 1) %% 12 + 1
}

# 使用简单的索引来直接返回季节
seasons <- c(
rep("Winter", 2),
rep("Spring", 3),
rep("Summer", 3),
rep("Autumn", 3),
"Winter"
)[months]

return(seasons)
}

7 函数 4

加入 hemisphere 参数的输入检查。

# 函数 4 ----
# __________
# 加入一些输入检查,
# 以确保 hemisphere 参数只有 north 或 south,
# 并给出默认错误提示或自动校正为 north。
date2season4 <- function(dates, hemisphere = "north") {
# 验证 hemisphere 参数,避免错误输入。
if (!hemisphere %in% c("north", "south")) {
stop("Invalid hemisphere. Please use 'north' or 'south'.")
}

months <- as.integer(format(dates, "%m"))

if (hemisphere == "south") {
months <- (months + 6 - 1) %% 12 + 1
}

seasons <- c(
rep("Winter", 2),
rep("Spring", 3),
rep("Summer", 3),
rep("Autumn", 3),
"Winter"
)[months]

return(seasons)
}

8 应用函数

# 应用函数 ----
# __________
matched_seasons1 <- date2season1(some_dates)
matched_seasons2 <- date2season2(some_dates)
matched_seasons3 <- date2season3(some_dates)
matched_seasons4 <- date2season4(some_dates)

9 检查是否一致

# 检查是否一致 ----
# __________
matched_seasons1 == matched_seasons2
[1] TRUE TRUE TRUE TRUE TRUE TRUE
matched_seasons1 == matched_seasons3
[1] TRUE TRUE TRUE TRUE TRUE TRUE
matched_seasons1 == matched_seasons4
[1] TRUE TRUE TRUE TRUE TRUE TRUE
matched_seasons2 == matched_seasons3
[1] TRUE TRUE TRUE TRUE TRUE TRUE
matched_seasons2 == matched_seasons4
[1] TRUE TRUE TRUE TRUE TRUE TRUE
matched_seasons3 == matched_seasons4
[1] TRUE TRUE TRUE TRUE TRUE TRUE

10 现成包里的函数

使用 hydroTSM 包。

# 安装新的包 ----
# __________
library(hydroTSM)
Warning: package 'hydroTSM' was built under R version 4.4.2
Loading required package: zoo
Warning: package 'zoo' was built under R version 4.4.2

Attaching package: 'zoo'
The following objects are masked from 'package:base':

as.Date, as.Date.numeric
library(stringr)

matched_seasons5 <- time2season(some_dates, out.fmt = "seasons")
matched_seasons5 # 得到的季节是小写。
[1] "summer" "winter" "spring" "summer" "autumn" "winter"
matched_seasons5 <- stringr::str_to_sentence(matched_seasons5) # 变为句首大写。
matched_seasons5 == matched_seasons1
[1] TRUE TRUE TRUE TRUE TRUE TRUE



ecologyR
🚀打赏可获取本公众号代码合集(见置顶文章)📌统计案例📌统计制图📌显著性标记📌结构方程模型可视化工具📌SEM教程与案例📌论文代码复现📌地图可视化
 最新文章