根据另一个变量求和

时间:2019-02-27 10:33:00

标签: r

我有一个由两个变量ContentsTime组成的数据集,如下所示:

Time          Contents
2017M01       123
2017M02       456
2017M03       789
.             .
.             .
.             .
2018M12       789

现在,我想创建一个将Contents聚合六个月的数字向量,也就是说,我想将2017M012017M06与一个数字,2017M07至{ {1}}到另一个数字,依此类推。

我可以通过建立索引的方式来执行此操作,但我希望能够在我的代码中写出:“从2017M01到2017M06的总和对应于该序列的内容”。

我非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您可以基于行数和要分组的元素数来创建分组变量。对于您的情况,您希望每6行进行分组,以便您的数据框应被6整除。使用iris进行演示(它有150行,因此150/6 = 25)

rep(seq(nrow(iris)%/%6), each = 6)
  #[1]  1  1  1  1  1  1  2  2  2  2  2  2  3  3  3  3  3  3  4  4  4  4  4  4  5  5  5  5  5  5  6  6  6  6  6  6  7  7  7  7  7  7  8  8  8  8  8  8  9  9  9  9  9  9 10 10 10 10
 #[59] 10 10 11 11 11 11 11 11 12 12 12 12 12 12 13 13 13 13 13 13 14 14 14 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 17 17 17 17 17 17 18 18 18 18 18 18 19 19 19 19 19 19 20 20
#[117] 20 20 20 20 21 21 21 21 21 21 22 22 22 22 22 22 23 23 23 23 23 23 24 24 24 24 24 24 25 25 25 25 25 25

有很多方法可以处理您的调用方式。这是一个自定义函数,可让您执行此操作(即创建分组变量),

f1 <- function(x, df) {
    v1 <- as.numeric(gsub('[0-9]{4}M(.*):[0-9]{4}M(.*)$', '\\1', x))
    v2 <- as.numeric(gsub('[0-9]{4}M(.*):[0-9]{4}M(.*)$', '\\2', x))
    i1 <- (v2 - v1) + 1
    return(rep(seq(nrow(df)%/%i1), each = i1))
}

f1("2017M01:2017M06", iris)
  #[1]  1  1  1  1  1  1  2  2  2  2  2  2  3  3  3  3  3  3  4  4  4  4  4  4  5  5  5  5  5  5  6  6  6  6  6  6  7  7  7  7  7  7  8  8  8  8  8  8  9  9  9  9  9  9 10 10 10 10
 #[59] 10 10 11 11 11 11 11 11 12 12 12 12 12 12 13 13 13 13 13 13 14 14 14 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 17 17 17 17 17 17 18 18 18 18 18 18 19 19 19 19 19 19 20 20
#[117] 20 20 20 20 21 21 21 21 21 21 22 22 22 22 22 22 23 23 23 23 23 23 24 24 24 24 24 24 25 25 25 25 25 25

编辑:通过将最终结果与<< 1的最终结果的重复值max+1连接起来,我们可以轻松地使函数与“非0余数”除法兼容。 em>剩余时间,即

f1 <- function(x, df) {
    v1 <- as.numeric(gsub('[0-9]{4}M(.*):[0-9]{4}M(.*)$', '\\1', x))
    v2 <- as.numeric(gsub('[0-9]{4}M(.*):[0-9]{4}M(.*)$', '\\2', x))
    i1 <- (v2 - v1) + 1
    final_v <- rep(seq(nrow(df) %/% i1), each = i1)
    if (nrow(df) %% i1 == 0) {
        return(final_v)
    } else {
        remainder = nrow(df) %% i1
        final_v1 <- c(final_v, rep((max(final_v) + 1), remainder))
        return(final_v1)
    }
}

因此,对于具有20行,每组6个的数据帧,上述函数将产生结果:

f1("2017M01:2017M06", df)
#[1] 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4