2014-09-03 2 views
1

У меня есть набор данных, напримерКак рассчитать среднее число определенных значений последовательных данных в R

a<-c(1,2,3,4,5,6,7,8,9) 

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

1:3,4:6,7:9 

Какую команду следует использовать?

+0

'путем (а, GL (потолке (длина (а)/3), 3, длина (а)), среднее значение)' – Vlo

+0

Вы имеете в виду потолок, но не потолок? – RATWSA

+0

есть. написал код без тестирования в R. sorry – Vlo

ответ

1

Это еще один способ:

Сделайте еще один вектор, который содержит различные уровни 1: 3, 4: 6, 7: 9

a<-c(1,2,3,4,5,6,7,8,9) 
b<-rep(1:3,each=3) 
x<-ave(a, b, FUN=mean) #use ave to find the means 
x 
#[1] 2 2 2 5 5 5 8 8 8 - gives this output 

x[seq(1, length(x), 3)] #this will output every 3rd element, giving: 
#[1] 2 5 8 

и, если вы хотите его на одной строке:

ave(a, rep(1:3,each=3), FUN=mean)[seq(1, length(a), 3)] 

и дополнительный способ - использовать некоторую прокатку в виде функции (например, из ZOO пакета или пакета TTR) и выберите 3-й элемент каждый:

library(TTR) 
runMean(a,3)[seq(3, length(a), 3)] 
#[1] 2 5 8 

и, конечно, этот принцип может быть распространен на базовый способ расчета прокатки средние:

filter(a, rep(1/3,3), sides=1)[seq(3, length(a), 3)] 
+0

Ни один из вышеперечисленных методов не может быть обобщен для 'length (a) %% 3! = 0' – Vlo

+0

@ Vlo - это не вопрос. Я отвечал на то, что было запрошено – jalapic

+0

(+1), некоторые полезные решения здесь, но я вместо вас переключу все '3' на 'n', чтобы сделать его более общим –

1

Вот возможный RcppRoll подход

library(RcppRoll) 
n <- 3 # The summing range 
a <- 1:9 # Your vector 
roll_mean(a, n)[seq_len(length(a) - n + 1) %% n == 1] 
## [1] 2 5 8 
1

1) rollapply Попробуйте это:

library(zoo) 
a <- 1:9 
rollapply(a, 3, mean, by = 3, align = "left", partial = TRUE) 
## [1] 2 5 8 

Он также работает, если длина a не кратна 3, и в этом случае она по-прежнему усредняет малую часть в конце. Если вы хотите, чтобы небольшая часть в конце была отброшена, опустите аргумент partial=TRUE. Если вы знаете, что длина a всегда кратная 3, тогда аргумент partial = TRUE может быть опущен, так как он не имеет никакого эффекта в этом случае.

2) tapply Вот второй альтернативный подход. c(gl(n, 3, n)) создает группировку вектор c(1, 1, 1, 2, 2, 2, ...)) длины n, а затем tapply применяется mean к значениям a в каждой группе:

n <- length(a) 
tapply(a, c(gl(n, 3, n)), mean) 
## 1 2 3 
## 2 5 8 

3) совокупности Подобно tapply, но дает кадр данных в качестве вывода:

n <- length(a) 
group <- gl(n, 3, n) 
aggregate(a ~ group, FUN = mean) 
## group a 
## 1  1 2 
## 2  2 5 
## 3  3 8 
0

Это сработало и для меня:

v <- 1:9 # a given vector 
gr <- 3 # consider a sequence of 3 consecutive elements 
length(v) <- prod(dim(matrix(v, nrow=gr))) # will stretch the vector with NA-s if needed 
colMeans(matrix(v, nrow=gr), na.rm=TRUE) 
[1] 2 5 8 

Необходимо обратить внимание на рециркуляцию при преобразовании из вектора в матрицу.Например:

v <- 1:11 
gr <- 3 
length(v) <- prod(dim(matrix(v, nrow=gr))); v 
[1] 1 2 3 4 5 6 7 8 9 10 11 NA 

# Will warn about the recycling 
# Warning message: 
# In matrix(v, nrow = gr) : 
# data length [11] is not a sub-multiple or multiple of the number of rows [3] 
# But the conversion will take place considering the NA-s: 

m <- matrix(v, nrow=gr); m 
    [,1] [,2] [,3] [,4] 
[1,] 1 4 7 10 
[2,] 2 5 8 11 
[3,] 3 6 9 NA 
colMeans(m, na.rm=TRUE) 
[1] 2.0 5.0 8.0 10.5 

вариант с data.table

dt <- data.table(1:11, rep(1:3,each=3)) 
dt 
    V1 V2 
1: 1 1 
2: 2 1 
3: 3 1 
4: 4 2 
5: 5 2 
6: 6 2 
7: 7 3 
8: 8 3 
9: 9 3 
10: 10 1 
11: 11 1 
dt[, mean(V1), by = rleid(V2)]$V1 
[1] 2.0 5.0 8.0 10.5 
Смежные вопросы