函数或循环到R中的子集移动平均值

时间:2015-03-25 22:38:01

标签: r apply subset moving-average

我是R中的循环和函数的新手。

想象一下,对于四个样品(A,B,C,D),我每0.1个单位的测量值从1.0到3.5。

我想找到1.5,2.5和3.5附近的平均测量值(+/- 0.2单位)。因此,对于1.5我平​​均c(1.3,1.4,1.5,1.6和1.7)等的值。

我如何撰写一份声明来总结所有四个样本的三个平均值?我想它可能会开始这样的事情:

X <- (1.5, 2.5, 3.5)

for (i in X)

{
  avg <- colMeans(subset(data,data$measurement > (i - 0.2) & data$measurement < (i + 0.2)))   
}

我也考虑过使用'['

colMeans(data[data$measurement > (i-0.2) & data$measurement < (i+0.2)]) 

感谢您的帮助到目前为止,sqldf是一个非常好的工具,该示例正是我想要的!

但是,我无法使用真实数据集。我修改了代码使它看起来像(抱歉,这不再与样本数据集对应):

M <- sqldf("select r.i,avg(w.X1),avg(w.X2),avg(w.X3),avg(w.X4)
           from Y r, Y w
           where w.i betreen r.i - 1 and r.i + 1
           group by r.i
           having r.i+0.0 in (600, 700, 800)")

为了对其进行语境化,我试图总结599-601,699-701和799-801的所有点的平均值,对于名为X1,X2,X3,X4的四列。我将此数据框命名为“Y&#39;”。行实际上是波长,数据指向在该波长处反射的光量。

您认为上述代码有什么问题吗? - 它创建一个具有正确尺寸的矩阵,但平均值与较大数据集中的平均值不匹配。我想知道我是否不理解代码中的某些内容,例如,&#39; w&#39;变量

1 个答案:

答案 0 :(得分:2)

正确的索引比循环更快。

library(zoo)
set.seed(1)
x <- as.character(seq(1,3.5,.1)) 
z <- zoo(data.frame(a=rnorm(length(x)),
                    b=rnorm(length(x)),
                    c=rnorm(length(x))),
         x)
z2 <- rollmean(z, k = 5, align = "center")[as.character(seq(1,3.5,.5)),]
> z2
              a           b          c
1.5  0.46601479  0.40153999  0.2007418
2    0.31015536 -0.22912642  0.4673692
2.5 -0.04141133  0.31978341  0.4350507
3    0.63816023 -0.07509644 -0.3622883

> data.frame(z2, index = index(z2))
              a           b          c index
1.5  0.46601479  0.40153999  0.2007418   1.5
2    0.31015536 -0.22912642  0.4673692     2
2.5 -0.04141133  0.31978341  0.4350507   2.5
3    0.63816023 -0.07509644 -0.3622883     3

如果要在窗口小于5宽的边缘上进行部分填充:

> rollapply(z, width = 5, align = "center", partial = TRUE, FUN = mean)[as.character(seq(1,3.5,.5)),]
              a           b           c
1   -0.42614637 -0.70156598  0.21492677
1.5  0.46601479  0.40153999  0.20074176 
2    0.31015536 -0.22912642  0.46736921 
2.5 -0.04141133  0.31978341  0.43505071
3    0.63816023 -0.07509644 -0.36228832
3.5 -0.47521823  0.22239574 -0.05024676

如果窗口大小不规则,但注释中提到的间距相等:

> z2 <- as.data.frame(z)
> z2$i <- row.names(z2)
> library(sqldf)
> sqldf("select a.i,avg(b.a),avg(b.b),avg(b.c) 
         from z2 a, z2 b 
         where b.i between a.i - .21 and a.i + .21 
         group by a.i 
         having a.i+0.0 in (1.5,2.0,2.5,3.0,3.5)")
    i    avg(b.a)    avg(b.b)    avg(b.c)
1 1.5  0.46601479  0.40153999  0.20074176
2   2  0.31015536 -0.22912642  0.46736921
3 2.5 -0.04141133  0.31978341  0.43505071
4   3  0.63816023 -0.07509644 -0.36228832
5 3.5 -0.47521823  0.22239574 -0.05024676