이동 평균 계산
R을 사용하여 행렬의 일련의 값에 대한 이동 평균을 계산하려고합니다. 일반적인 R 메일 링리스트 검색은 그다지 도움이되지 못했습니다. R 에는 내장 함수 가 없어 움직이는 평균을 계산할 수 있습니다. 패키지가 하나를 제공합니까? 아니면 내가 직접 써야합니까?
또는 필터를 사용하여 간단히 계산할 수 있습니다. 다음은 내가 사용하는 기능입니다.
ma <- function(x, n = 5){filter(x, rep(1 / n, n), sides = 2)}
를 사용하는 경우 위 기능에서 dplyr
주의해서 지정 stats::filter
하십시오.
사용 cumsum
이 충분하고 효율적이어야합니다. 벡터 x가 있고 n의 누계 합을 원한다고 가정합니다.
cx <- c(0,cumsum(x))
rsum <- (cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]) / n
@mzuther의 의견에서 지적했듯이 데이터에 NA가 없다고 가정합니다. 이를 처리하려면 각 창을 비 NA 값의 수로 나누어야합니다. @Ricardo Cruz의 의견을 통합하여 한 가지 방법이 있습니다.
cx <- c(0, cumsum(ifelse(is.na(x), 0, x)))
cn <- c(0, cumsum(ifelse(is.na(x), 0, 1)))
rx <- cx[(n+1):length(cx)] - cx[1:(length(cx) - n)]
rn <- cn[(n+1):length(cx)] - cn[1:(length(cx) - n)]
rsum <- rx / rn
이것은 여전히 창의 모든 값이 NA이면 0으로 나누기 오류가 발생한다는 문제가 있습니다.
에서 data.table 1.12.0 새로운 frollmean
기능은 빠르고 정확한 신중 평균 압연 처리를 계산하기 위해 추가되었습니다 NA
, NaN
그리고 +Inf
, -Inf
값을.
문제에 재현 가능한 예가 없으므로 여기에서 다루는 것이 많지 않습니다.
?frollmean
매뉴얼 에 대한 자세한 내용 은 온라인에서 확인할 수도 있습니다 ?frollmean
.
아래 매뉴얼의 예 :
library(data.table)
d = as.data.table(list(1:6/2, 3:8/4))
# rollmean of single vector and single window
frollmean(d[, V1], 3)
# multiple columns at once
frollmean(d, 3)
# multiple windows at once
frollmean(d[, .(V1)], c(3, 4))
# multiple columns and multiple windows at once
frollmean(d, c(3, 4))
## three above are embarrassingly parallel using openmp
이 caTools
패키지는 매우 빠른 롤링 평균 / 최소 / 최대 / sd를 가지며 다른 기능은 거의 없습니다. 난 단지와 함께 작업 한 runmean
및 runsd
그들은 지금까지 언급 한 다른 패키지의 가장 빠른입니다.
RcppRoll
C ++로 작성된 매우 빠른 이동 평균에 사용할 수 있습니다 . 그냥 roll_mean
함수를 호출하십시오 . 문서는 여기 에서 찾을 수 있습니다 .
그렇지 않으면이 (느린) for 루프가 트릭을 수행해야합니다.
ma <- function(arr, n=15){
res = arr
for(i in n:length(arr)){
res[i] = mean(arr[(i-n):i])
}
res
}
실제로 RcppRoll
매우 좋습니다.
cantdutch 가 게시 한 코드는 네 번째 줄에서 수정하여 창에 고정시켜야합니다.
ma <- function(arr, n=15){
res = arr
for(i in n:length(arr)){
res[i] = mean(arr[(i-n+1):i])
}
res
}
누락을 처리하는 다른 방법은 여기에 있습니다 .
A third way, improving cantdutchthis code to calculate partial averages or not, follows:
ma <- function(x, n=2,parcial=TRUE){
res = x #set the first values
if (parcial==TRUE){
for(i in 1:length(x)){
t<-max(i-n+1,1)
res[i] = mean(x[t:i])
}
res
}else{
for(i in 1:length(x)){
t<-max(i-n+1,1)
res[i] = mean(x[t:i])
}
res[-c(seq(1,n-1,1))] #remove the n-1 first,i.e., res[c(-3,-4,...)]
}
}
In order to complement the answer of cantdutchthis and Rodrigo Remedio;
moving_fun <- function(x, w, FUN, ...) {
# x: a double vector
# w: the length of the window, i.e., the section of the vector selected to apply FUN
# FUN: a function that takes a vector and return a summarize value, e.g., mean, sum, etc.
# Given a double type vector apply a FUN over a moving window from left to the right,
# when a window boundary is not a legal section, i.e. lower_bound and i (upper bound)
# are not contained in the length of the vector, return a NA_real_
if (w < 1) {
stop("The length of the window 'w' must be greater than 0")
}
output <- x
for (i in 1:length(x)) {
# plus 1 because the index is inclusive with the upper_bound 'i'
lower_bound <- i - w + 1
if (lower_bound < 1) {
output[i] <- NA_real_
} else {
output[i] <- FUN(x[lower_bound:i, ...])
}
}
output
}
# example
v <- seq(1:10)
# compute a MA(2)
moving_fun(v, 2, mean)
# compute moving sum of two periods
moving_fun(v, 2, sum)
Though a bit slow but you can also use zoo::rollapply to perform calculations on matrices.
reqd_ma <- rollapply(x, FUN = mean, width = n)
where x is the data set, FUN = mean is the function; you can also change it to min, max, sd etc and width is the rolling window.
참고URL : https://stackoverflow.com/questions/743812/calculating-moving-average
'IT' 카테고리의 다른 글
Hudson이 지원하는 JUnit XML 형식 사양은 무엇입니까? (0) | 2020.05.24 |
---|---|
cout은 std의 회원이 아닙니다 (0) | 2020.05.24 |
'box-shadow-color'속성이 있습니까? (0) | 2020.05.23 |
OS X Lion에서 터미널이 ~ / .bashrc를로드하지 않는 문제를 해결하는 방법 (0) | 2020.05.23 |
키를 포함한 PHP의 array_map (0) | 2020.05.23 |