避免R中的循环

时间:2009-12-11 06:49:03

标签: r loops

我决定学习R.我试图了解如何编写“R风格”函数并避免循环。以下是一个示例情况:

给定一个向量a,我想计算一个向量b,其元素b[i](向量索引从1开始)定义如下:

1 <= i <= 4:
b[i] = NaN

5 <= i <= length(a):
b[i] = mean(a[i-4] to a[i])

基本上,如果我们假装'a'是第一个条目在时间= 0的速度列表,第二个在时间= 1秒,第三个在时间= 2秒......我想获得一个相应的矢量描述了过去5秒内的平均速度。

例如为: 如果a is (1,1,1,1,1,4,6,3,6,8,9)b应为(NaN, NaN, NaN, NaN, 1, 1.6, 2.6, 3, 4, 5.4, 6.4)

我可以使用循环来做到这一点,但我觉得这样做不会是“R风格”。

谢谢,

Tungata

3 个答案:

答案 0 :(得分:5)

由于这些滚动功能通常适用于时间序列数据,因此一些较新且更丰富的时间序列数据处理包已经为您做到了这一点:

R> library(zoo)   ## load zoo
R> speed <- c(1,1,1,1,1,4,6,3,6,8,9)
R> zsp <- zoo( speed, order.by=1:length(speed) )  ## creates a zoo object
R> rollmean(zsp, 5)                               ## default use
  3   4   5   6   7   8   9 
1.0 1.6 2.6 3.0 4.0 5.4 6.4 
R> rollmean(zsp, 5, na.pad=TRUE, align="right")   ## with padding and aligned
  1   2   3   4   5   6   7   8   9  10  11 
 NA  NA  NA  NA 1.0 1.6 2.6 3.0 4.0 5.4 6.4 
R> 

zoo有出色的文档,可以向您展示更多,更多的示例,特别是如何使用真实(可能是不规则的)日期执行此操作; xts进一步扩展了这一点,但zoo是一个更好的起点。

答案 1 :(得分:3)

b = filter(a, rep(1.0/5, 5), sides=1)之类的东西可以完成这项工作,虽然你可能会在前几个插槽中获得零而不是NaN。 R有一个庞大的内置函数库,“R风格”就是尽可能使用它们。请查看filter函数的文档。

答案 2 :(得分:1)

您还可以使用cumsumdiff的组合来获得滑动窗口的总和。不过,您需要使用自己的NaN填充:

> speed <- c(1,1,1,1,1,4,6,3,6,8,9)
> diff(cumsum(c(0,speed)), 5)/5
[1] 1.0 1.6 2.6 3.0 4.0 5.4 6.4