创建循环的数字序列
create sequence of numbers which are cyclic
我有一个月份向量
m_vec <- c(3, 7, 11)
这些月份代表一个季节的开始月份。每个季节的所有月份如下所示:
season1 <- c(3,4,5,6)
season2 <- c(7,8,9,10)
season3 <- c(11,12,1,2)
我想创建一个小函数,它接受开始月份和
生成每个季节的月份向量。下面显示了更多示例:
m_vec <- c(9,12,4,8)
season1 <- c(9,10,11)
season2 <- c(12,1,2,3)
season3 <- c(4,5,6,7,8)
m_vec <- c(12, 5, 9)
season1 <- c(12, 1, 2,3,4)
season2 <- c(5,6,7,8)
season3 <- c(9,10,11)
我的 for 循环不完整,我什至不知道从哪里开始使用逻辑
n_season <- length(m_vec)
temp_list <- list()
for(m in seq_along(m_vec)){
month_start <- m_vec[m]
month_start_next <- m_vec[m + 1]
month_start:month_start_next
}
首先我们可以创建一些辅助函数
cycle <- function(n) { function(x) (x-1) %% n + 1 }
split_at <- function(b) { function(x) split(x, cumsum(x %in% b)) }
cycle()
助手将 return 一个函数,它将值保持在从 1 到您传入的 n
范围内。它使用模数 %
操作员。 split_at
助手将 return 一个函数,该函数接受一个向量并在找到您传入的值时将其拆分。它通过使用 cumsum()
计算找到每个断点的时间来做到这一点。
然后我们可以接受您的输入,从您的第一个开始月份创建一个 12 个月的向量,将其包装在循环仪中以使其保持在 1-12 之间,然后我们可以使用您的季节断点将其拆分。这是它的样子:
month_cycle <- cycle(12)
season_splitter <- split_at(m_vec)
m_vec <- c(12, 5, 9)
seq(m_vec[1], length.out=12) |>
month_cycle() |>
season_splitter()
# $`1`
# [1] 12 1 2 3 4
# $`2`
# [1] 5 6 7 8
# $`3`
# [1] 9 10 11
一个选项是转换为 Date
class,获取 seq
uence 并提取 month
s
library(lubridate)
fn1 <- function(mvec) {
new <- pmax(mvec-1, 1)
out <- Map(function(i, j) {
date1 <- mdy(i, truncated = 2)
date2 <- mdy(j, truncated = 2)
if(date1 > date2) {
date2 <- date2 + years(1)}
month(seq(date1, date2, by = "month"))
}, mvec, c(new[-1], new[1]))
if(length(out[[length(out)]]) < 2) {
out[[length(out)-1]] <- c(out[[length(out)-1]], out[[length(out)]])
out[[length(out)]] <- NULL
}
names(out) <- paste0("season", seq_along(out))
return(out)
}
-测试
> fn1(m_vec)
$season1
[1] 3 4 5 6
$season2
[1] 7 8 9 10
$season3
[1] 11 12 1 2
> fn1(c(9, 12, 4, 8))
$season1
[1] 9 10 11
$season2
[1] 12 1 2 3
$season3
[1] 4 5 6 7 8
> fn1(c(1, 5, 11))
$season1
[1] 1 2 3 4
$season2
[1] 5 6 7 8 9 10
$season3
[1] 11 12 1
m_vec <- c(12, 5, 9)
Map(function(x, y) head((((x:(x + ((y - x) %% 12))) - 1) %% 12) + 1, -1),
m_vec,
c(m_vec[-1], m_vec[1]))
#[[1]]
#[1] 12 1 2 3 4
#[[2]]
#[1] 5 6 7 8
#[[3]]
#[1] 9 10 11
我有一个月份向量
m_vec <- c(3, 7, 11)
这些月份代表一个季节的开始月份。每个季节的所有月份如下所示:
season1 <- c(3,4,5,6)
season2 <- c(7,8,9,10)
season3 <- c(11,12,1,2)
我想创建一个小函数,它接受开始月份和 生成每个季节的月份向量。下面显示了更多示例:
m_vec <- c(9,12,4,8)
season1 <- c(9,10,11)
season2 <- c(12,1,2,3)
season3 <- c(4,5,6,7,8)
m_vec <- c(12, 5, 9)
season1 <- c(12, 1, 2,3,4)
season2 <- c(5,6,7,8)
season3 <- c(9,10,11)
我的 for 循环不完整,我什至不知道从哪里开始使用逻辑
n_season <- length(m_vec)
temp_list <- list()
for(m in seq_along(m_vec)){
month_start <- m_vec[m]
month_start_next <- m_vec[m + 1]
month_start:month_start_next
}
首先我们可以创建一些辅助函数
cycle <- function(n) { function(x) (x-1) %% n + 1 }
split_at <- function(b) { function(x) split(x, cumsum(x %in% b)) }
cycle()
助手将 return 一个函数,它将值保持在从 1 到您传入的 n
范围内。它使用模数 %
操作员。 split_at
助手将 return 一个函数,该函数接受一个向量并在找到您传入的值时将其拆分。它通过使用 cumsum()
计算找到每个断点的时间来做到这一点。
然后我们可以接受您的输入,从您的第一个开始月份创建一个 12 个月的向量,将其包装在循环仪中以使其保持在 1-12 之间,然后我们可以使用您的季节断点将其拆分。这是它的样子:
month_cycle <- cycle(12)
season_splitter <- split_at(m_vec)
m_vec <- c(12, 5, 9)
seq(m_vec[1], length.out=12) |>
month_cycle() |>
season_splitter()
# $`1`
# [1] 12 1 2 3 4
# $`2`
# [1] 5 6 7 8
# $`3`
# [1] 9 10 11
一个选项是转换为 Date
class,获取 seq
uence 并提取 month
s
library(lubridate)
fn1 <- function(mvec) {
new <- pmax(mvec-1, 1)
out <- Map(function(i, j) {
date1 <- mdy(i, truncated = 2)
date2 <- mdy(j, truncated = 2)
if(date1 > date2) {
date2 <- date2 + years(1)}
month(seq(date1, date2, by = "month"))
}, mvec, c(new[-1], new[1]))
if(length(out[[length(out)]]) < 2) {
out[[length(out)-1]] <- c(out[[length(out)-1]], out[[length(out)]])
out[[length(out)]] <- NULL
}
names(out) <- paste0("season", seq_along(out))
return(out)
}
-测试
> fn1(m_vec)
$season1
[1] 3 4 5 6
$season2
[1] 7 8 9 10
$season3
[1] 11 12 1 2
> fn1(c(9, 12, 4, 8))
$season1
[1] 9 10 11
$season2
[1] 12 1 2 3
$season3
[1] 4 5 6 7 8
> fn1(c(1, 5, 11))
$season1
[1] 1 2 3 4
$season2
[1] 5 6 7 8 9 10
$season3
[1] 11 12 1
m_vec <- c(12, 5, 9)
Map(function(x, y) head((((x:(x + ((y - x) %% 12))) - 1) %% 12) + 1, -1),
m_vec,
c(m_vec[-1], m_vec[1]))
#[[1]]
#[1] 12 1 2 3 4
#[[2]]
#[1] 5 6 7 8
#[[3]]
#[1] 9 10 11