Рассчитать среднее значение для конкретного шаблона строки - PullRequest
1 голос
/ 28 мая 2019

У меня есть такой фрейм данных:

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, 13, 25, 37), то всегда +4, а для следующих 4 это означает, что он просто отступает еще на 1 строку вниз.

Я хотел бы получить вывод всех этих средств в одном списке.

Есть идеи? ПРИМЕЧАНИЕ. В этом примере среднее значение, конечно же, всегда является средним числом, но мое реальное значение df отличается.

Ответы [ 4 ]

2 голосов
/ 28 мая 2019

Идея с помощью базы 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 голосов
/ 28 мая 2019

Не совсем уверен, какой формат вывода вам нужен, но следующие коды могут вычислить, что вы хотите, так или иначе.

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 голос
/ 28 мая 2019

Поскольку вы сказали, что хотите получить длинный список средств, я предположил, что это также может быть вектор, в котором у вас просто есть все эти значения. Вы получите это так:

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)
}
1 голос
/ 28 мая 2019

И еще один способ.

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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...