对某些行使用rollapply

时间:2014-07-17 13:59:22

标签: r zoo dplyr

我想知道是否可以仅对数据帧的某些行使用rollapply()。我知道“by”参数可以指定我计算FUN的每个第s个时间点,但现在我有一个非常特定的行索引向量,我希望应用rollapply()。例如,我有以下dataframe

df <- data.frame(x = (1:10), y = (11:20))

我知道当滚动宽度为3时如何计算y列的滚动平均值。

library(zoo)
m <- rollapply(df$y, width = 3, FUN = mean, fill = NA, align = "right")

但是,如果我只想要第4和第9行的宽度3均值怎么办?我可以操纵“by”参数中的某些东西吗?或者其他一些更好的方法(使用apply进行滚动计算可能)?

2 个答案:

答案 0 :(得分:0)

希望我能正确理解你的问题。我想你问的是如何在滑动窗口中的每个第4和第9个元素上执行一个函数?如果是,只需使用x [4]和x [9]将函数限制为第4和第9个元素。像这样:

output <- rollapply(df, 9, function(x) (x[4] + x[9])/2), fill = NA, align = "right")

我还将你的问题解释为当窗口包含第4行或第9行时如何获得均值?这可以通过子设置来完成。您需要考虑的问题是您希望第4行和第9行位于窗口内。您希望第4行位于窗口中的位置x [1],x [2]或x [3]吗?取决于其他位置的内容将明显影响您的输出。假设您不知道,并且所有三个看起来都合理,您将需要编写一个函数a来创建包含您感兴趣的数据范围的数据帧列表,然后使用apply函数或for循环来rollapply对列表中每个数据帧的平均函数。然后,您可以将所有这些输出转换为数据帧以进一步处理。像这样:

# the rlist library has a function that allows us to add items to a list 
# which will be handy later on
library(rlist)
library(zoo)

# your example data
df <- data.frame(x = (1:10), y = (11:20))

# a vector of your desired rows
desired_rows <- c(4,9)

# A for loop that generates a list of dataframes
# with your desired rows in the middle of each
for (i in desired_rows){
  lower_bound <- i-2
  upper_bound <- i+2

  df_subset <- df[c(lower_bound:upper_bound), ]


  if(exists("list_df_range")){
    list_df_range <- list.append(list_df_range, df_subset)

  }else{

  list_df_range <- list(df_subset)

  }
}

# a second for loop that applies your rollapply function to each
# data frame in the list and then
# returns a dataframe of the final results
# with each column named after the originating row

for (n in list_df_range){

  m <- rollapply(n$y, width = 3, FUN = mean, fill = NA, align = "right")

  if(exists("final_out")){
    final_out <- cbind(final_out, m)

  }else{
    final_out <- data.frame(m)

  }

}


names(final_out) <- desired_rows

答案 1 :(得分:0)

基于海报问题下面的评论,似乎想要的是取每个窗口中宽度为3的滚动窗口的平均值,不包括每个窗口中的中间元素,只保留第4和第9个元素

cc <- c(4, 9)

rollapply(df$y, list(c(-2, 0)), mean, fill = NA)[cc]
## [1] 13 18

rollapplyr(df$y, 3, function(x) mean(x[-2]), fill = NA)[cc]
## [1] 13 18

sapply(cc, function(ix) mean(df$y[seq(to = ix, by = 2, length = 2)]))
## [1] 13 18

(df$y[cc - 2] + df$y[cc]) / 2
## [1] 13 18