生成每3个月值的序列

时间:2018-03-05 00:10:08

标签: r lapply seq recycle

问题

如何修改seq()以生成12个数字向量的列表,每个向量包含从感兴趣的月份开始每3个月出现的月份?

我要求每个月在每个向量中至少有3个值。我不确定如何在我目前使用的seq中回收值1到12。任何指导都将非常感谢!

可重复的示例

# create every three month values
list.of.month.values <-
    list( JAN = 1
          , FEB = 2
          , MAR = 3
          , APR = 4
          , MAY = 5
          , JUN = 6
          , JUL = 7
          , AUG = 8
          , SEP = 9
          , OCT = 10
          , NOV = 11
          , DEC = 12 )

# find each month's 
# values that appear every three months
every.three.month.values <-
    lapply(
        X = list.of.month.values
        , FUN = function( i )
            seq( from = i, to = 12, by = 3 )
    )

# view results
every.three.month.values
# $JAN
# [1]  1  4  7 10
# 
# $FEB
# [1]  2  5  8 11
# 
# $MAR
# [1]  3  6  9 12
# 
# $APR
# [1]  4  7 10
# 
# $MAY
# [1]  5  8 11
# 
# $JUN
# [1]  6  9 12
# 
# $JUL
# [1]  7 10
# 
# $AUG
# [1]  8 11
# 
# $SEP
# [1]  9 12
# 
# $OCT
# [1] 10
# 
# $NOV
# [1] 11
# 
# $DEC
# [1] 12

# This works for the first 6 months.
# But we need all twelve months
every.three.month.values$JUL <- c( 7, 10, 1 )
every.three.month.values$AUG <- c( 8, 11, 2 )
every.three.month.values$SEP <- c( 9, 12, 3 )
every.three.month.values$OCT <- c( 10, 1, 4 )
every.three.month.values$NOV <- c( 11, 2, 5 )
every.three.month.values$DEC <- c( 12, 3, 6 )

# end of script #

期望输出

这是我想要的输出:

structure(list(JAN = c(1, 4, 7, 10), FEB = c(2, 5, 8, 11), MAR = c(3, 
6, 9, 12), APR = c(4, 7, 10), MAY = c(5, 8, 11), JUN = c(6, 9, 
12), JUL = c(7, 10, 1), AUG = c(8, 11, 2), SEP = c(9, 12, 3), 
    OCT = c(10, 1, 4), NOV = c(11, 2, 5), DEC = c(12, 3, 6)), .Names = c("JAN", 
"FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", 
"NOV", "DEC"))

1 个答案:

答案 0 :(得分:4)

你可以这样做:

df <- sapply(seq(1, 12, by = 3), function(x) 
    ((seq(x, 12 + x - 1, by = 1) - 1) %% 12) + 1);
rownames(df) <- names(list.of.month.values);
#    [,1] [,2] [,3] [,4]
#JAN    1    4    7   10
#FEB    2    5    8   11
#MAR    3    6    9   12
#APR    4    7   10    1
#MAY    5    8   11    2
#JUN    6    9   12    3
#JUL    7   10    1    4
#AUG    8   11    2    5
#SEP    9   12    3    6
#OCT   10    1    4    7
#NOV   11    2    5    8
#DEC   12    3    6    9

请注意,这与您的预期结果并不完全相同;我不理解为什么在您的输出中JANFEBMAR有4个元素,但剩下的几个月只有3个元素。

可以通过

重现您的预期输出
lst <- apply(df, 1, function(x) if (x[1] < 4) x else x[-length(x)]);
names(lst) <- names(list.of.month.values);
#$JAN
#[1]  1  4  7 10
#
#$FEB
#[1]  2  5  8 11
#
#$MAR
#[1]  3  6  9 12
#
#$APR
#[1]  4  7 10
#
#$MAY
#[1]  5  8 11
#
#$JUN
#[1]  6  9 12
#
#$JUL
#[1]  7 10  1
#
#$AUG
#[1]  8 11  2
#
#$SEP
#[1]  9 12  3
#
#$OCT
#[1] 10  1  4
#
#$NOV
#[1] 11  2  5
#
#$DEC
#[1] 12  3  6

但这似乎不必要地丑陋/ kludgy。