Giá trị trung bình trượt
Giá trị trung bình trượt (đôi khi gọi là moving averages) được dùng trong phân tích chuỗi thời gian để làm mượt nhiễu. Giá trị tại mỗi thời điểm được thay bằng trung bình của các giá trị ở những thời điểm lân cận (gọi là cửa sổ).
Một cách tự nhiên để viết hàm này là
rollmean1 <- function(x, window = 3) {
n <- length(x)
res <- rep(NA, n)
for(i in seq(window, n)) {
res[i] <- mean(x[seq(i - window + 1, i)])
}
res
}
Cách này gọi mean() rất nhiều lần, nên kém hiệu quả. Một giải pháp là dùng biến total để ở mỗi vòng lặp bạn loại phần tử không còn cần và cộng phần tử mới vào.
rollmean2 <- function(x, window = 3){
n <- length(x)
res <- rep(NA, n)
total <- sum(head(x, window))
res[window] <- total / window
for(i in seq(window + 1, n)) {
total <- total + x[i] - x[i - window]
res[i] <- total / window
}
res
}
Dù theo cách nào, viết mã vòng lặp tự nhiên hơn so với mã vector hóa, nhưng điều đó có thể làm giảm hiệu năng. Cả hai phiên bản trên đều kém hiệu quả theo cách riêng của chúng. Trước khi làm phiên bản C++ ở bài tập tiếp theo, hãy viết một phiên bản dùng vector hóa. rollmean1(), rollmean2(), và một vector ngẫu nhiên x đã có sẵn trong không gian làm việc của bạn. Bây giờ bạn sẽ hoàn thiện định nghĩa hàm rollmean3() và đo hiệu năng của các hàm này.
Bài tập này là một phần của khóa học
Tối ưu hóa mã R với Rcpp
Bài tập tương tác thực hành trực tiếp
Hãy thử làm bài tập này bằng cách hoàn thành đoạn mã mẫu này.
# Complete the definition of rollmean3()
rollmean3 <- function(x, window = 3) {
# Add the first window elements of x
initial_total <- ___(head(x, window))
# The elements to add at each iteration
lasts <- tail(x, - window)
# The elements to remove
firsts <- head(x, - window)
# Take the initial total and add the
# cumulative sum of lasts minus firsts
other_totals <- ___ + ___(___ - firsts)
# Build the output vector
c(
rep(NA, window - 1), # leading NA
initial_total / ___, # initial mean
other_totals / ___ # other means
)
}