【问题标题】:R moving average function to deal with values less window sizeR移动平均函数来处理较小窗口大小的值
【发布时间】:2017-09-21 17:37:13
【问题描述】:

按照this 的回答,我使用了移动平均函数,窗口大小为 2、3 和 4。

require(zoo)
#MOVING AVERAGE FUNCTION
get.mav <- function(df, n = 2){
  if(length(df) < n){
    return(df)
  } 
  c(df[1:(n-1)],rollapply(df,width = n, mean, align="right"))
}

#DATA FRAME (dummy)
ID <- c("d","b","a","a","c","e","b","d","b","b")
Value <- c(4,5,5,3,2,1,6,9,5,5)
df <-data.frame(ID,Value)

# FUNCTION IMPLEMENTATION
df <- with(df,df[order(ID),])
df$mav2 <- unlist(aggregate(Value~ID,df,get.mav,na.action = NULL,n=2)$Value) 
df$mav3 <- unlist(aggregate(Value~ID,df,get.mav,na.action = NULL,n=3)$Value) 
df$mav4 <- unlist(aggregate(Value~ID,df,get.mav,na.action = NULL,n=4)$Value) 

#OUTPUT
ID  Value   mav2    mav3    mav4
a   5   5   5   5
a   3   4   3   3
b   5   5   5   5
b   6   5.5 6   6
b   5   5.5 5.3 5
b   5   5   5.3 5.25
c   2   2   2   2
d   4   4   4   4
d   9   6.5 9   9
e   1   1   1   1

函数get.mav 完全按照它应该的方式工作。我想改变这个功能,这样

对于大小为 3 的窗口,如果 df 长度为 2,则取这两个元素的平均值,而不是简单地返回 df。

对于大小为 4 的窗口类似,如果长度为 3 或 2,则取这三个或两个元素的平均值,而不是简单地返回 df。

我尝试了 if 语句,但比较无法正常工作。任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: r dplyr zoo


    【解决方案1】:

    对于每个宽度,使用 ave 以通过 ID 调用 rollapplyrpartial = TRUE in rollapplyr 导致它平均开始附近的部分点数。

    library(zoo)
    
    roll <- function(x, group, w) {
       ave(x, group, FUN = function(x) rollapplyr(x, w, mean, partial = TRUE))
    }
    
    transform(df[order(df$ID), ], 
       mav2 = roll(Value, ID, 2), 
       mav3 = roll(Value, ID, 3), 
       mav4 = roll(Value, ID, 4)
    )
    

    或者:

    w <- 2:4
    names(w) <- paste0("mav", w)
    
    with(df[order(df$ID), ],
       data.frame(ID, Value, lapply(w, roll, x = Value, group = ID), check.names = FALSE)
    )
    

    两者都给出:

       ID Value mav2     mav3     mav4
    1   a     5  5.0 5.000000 5.000000
    2   a     3  4.0 4.000000 4.000000
    3   b     5  5.0 5.000000 5.000000
    4   b     6  5.5 5.500000 5.500000
    5   b     5  5.5 5.333333 5.333333
    6   b     5  5.0 5.333333 5.250000
    7   c     2  2.0 2.000000 2.000000
    8   d     4  4.0 4.000000 4.000000
    9   d     9  6.5 6.500000 6.500000
    10  e     1  1.0 1.000000 1.000000
    

    更新:已修复。

    【讨论】:

      猜你喜欢
      • 2020-03-29
      • 1970-01-01
      • 2020-07-04
      • 2018-08-18
      • 1970-01-01
      • 2019-02-11
      • 1970-01-01
      • 2022-01-03
      • 2022-09-24
      相关资源
      最近更新 更多