计算特定行模式的平均值

时间:2019-05-28 13:14:01

标签: r dataframe row sequence mean

我有一个这样的数据框:

V1 = paste0("AB", seq(1:48))
V2 = seq(1:48)

test = data.frame(name = V1, value = V2)

我想计算值列和特定行的均值。

行的模式非常复杂:

Rows of MeanA1: 1, 5, 9
Rows of MeanA2: 2, 6, 10
Rows of MeanA3: 3, 7, 11
Rows of MeanA4: 4, 8, 12

Rows of MeanB1: 13, 17, 21
Rows of MeanB2: 14, 18, 22
Rows of MeanB3: 15, 19, 23
Rows of MeanB4: 16, 20, 24

Rows of MeanC1: 25, 29, 33
Rows of MeanC2: 26, 30, 34
Rows of MeanC3: 27, 31, 35
Rows of MeanC4: 28, 32, 36

Rows of MeanD1: 37, 41, 45
Rows of MeanD2: 38, 42, 46
Rows of MeanD3: 39, 43, 47
Rows of MeanD4: 40, 44, 48

如您所见,它从4个不同的点(1、3、25、37)开始,然后始终为+4,接下来的4表示其仅向下移动了1行。

我希望将所有这些均值输出在一个列表中。

有什么想法吗?注意:在此示例中,平均值当然始终是中间数字,但我的实际df不同。

4 个答案:

答案 0 :(得分:2)

不确定所需的输出格式,但是以下代码可以计算出所需的内容。

calc_mean1 <- function(x) mean(test$value[seq(x, by = 4, length.out = 3)])
calc_mean2 <- function(x){sapply(x:(x+3), calc_mean1)}
output <- lapply(seq(1, 37, 12), calc_mean2)
names(output) <- paste0('Mean', LETTERS[seq_along(output)]) # remove this line if more than 26 groups.
output

## $MeanA
## [1] 5 6 7 8

## $MeanB
## [1] 17 18 19 20

## $MeanC
## [1] 29 30 31 32

## $MeanD
## [1] 41 42 43 44

答案 1 :(得分:2)

通过基数R的想法是为每4行创建一个分组变量,每12行(nrow(test) / 4)拆分数据,然后汇总以找到均值,即

test$new = rep(1:4, nrow(test)%/%4)
lapply(split(test, rep(1:4, each = nrow(test) %/% 4)), function(i)
                                              aggregate(value ~ new, i, mean))

#    $`1`
#      new value
#    1   1     5
#    2   2     6
#    3   3     7
#    4   4     8

#    $`2`
#      new value
#    1   1    17
#    2   2    18
#    3   3    19
#    4   4    20

#    $`3`
#      new value
#    1   1    29
#    2   2    30
#    3   3    31
#    4   4    32

#    $`4`
#      new value
#    1   1    41
#    2   2    42
#    3   3    43
#    4   4    44

答案 2 :(得分:1)

还有另一种方式。

fun <- function(DF, col, step = 4){
  run <- nrow(DF)/step^2
  res <- lapply(seq_len(step), function(inc){
    inx <- seq_len(run*step) + (inc - 1)*run*step
    dftmp <- DF[inx, ]
    tapply(dftmp[[col]], rep(seq_len(step), run), mean, na.rm = TRUE)
  })
  names(res) <- sprintf("Mean%s", LETTERS[seq_len(step)])
  res
}

fun(test, 2, 4)
#$MeanA
#1 2 3 4 
#5 6 7 8 
#
#$MeanB
# 1  2  3  4 
#17 18 19 20 
#
#$MeanC
# 1  2  3  4 
#29 30 31 32 
#
#$MeanD
# 1  2  3  4 
#41 42 43 44 

答案 3 :(得分:1)

因为您说过想要一长串的平均值,所以我认为它也可以是向量,您只要拥有所有这些值即可。你会得到这样的:

V1 = paste0("AB", seq(1:48))
V2 = seq(1:48)

test = data.frame(name = V1, value = V2)
meanVector <- NULL

for (i in 1:(nrow(test)-8)) {
  x <- c(test$value[i], test$value[i+4], test$value[i+8])
  m <- mean(x)
  meanVector <- c(meanVector, m)
}