8

可能重复:
`ddply`(或类似的)可以做一个滑动窗口吗?

是否有类似 rollapply 的函数(标准 R 或 CRAN 包中)在 data.frame 上运行,但不会将其转换为矩阵。rollapply 可以与 data.frame 一起使用,但如果 data.frame 具有混合类型,则每个数据窗口都将转换为字符(矩阵)。

我更喜欢支持 width、na.pad、align 等的函数,就像 rollapply

例子

采用混合类型的任何 data.frame

test = data.frame( Name = c( "bob" , "jane" , "joe" ) , Points = c( 4 , 9 , 1 ) )

假设您想滚动窗口大小为 2。 FUN 的第一次迭代使用仅包含测试的第 1 行和第 2 行的 data.frame 调用。

所以RollapplyThatRespectsDataFrame( ... , FUN = function( x ) { ... } )在第一次迭代时会设置x = data.frame( Name = c( "bob" , "jane" ) , Points = c( 4 , 9 ) )

第二次迭代是一个 data.frame 的第 2 行和第 3 行test

基本上,这个新函数与 rollapply 做同样的事情,除了它可以与 data.frames 一起正常工作。它不会转换为矩阵。

4

1 回答 1

8

尝试这个:

> library(zoo)
> DF <- data.frame(a = 1:10, b = 21:30, c = letters[1:10])
> replace(DF, 1:2, rollapply(DF[1:2], 3, sum, fill = NA))
    a  b c
1  NA NA a
2   6 66 b
3   9 69 c
4  12 72 d
5  15 75 e
6  18 78 f
7  21 81 g
8  24 84 h
9  27 87 i
10 NA NA j

关于经过一些讨论后添加到问题中的示例,可以通过将此类功能rollapply应用于行索引来将其分层:

> lapply(as.data.frame(t(rollapply(1:nrow(test), 2, c))), function(ix)test[ix, ])
$V1
  Name Points
1  bob      4
2 jane      9

$V2
  Name Points
2 jane      9
3  joe      1

在这里它被包裹得更好一点:

rollapply.data.frame <- function(data, ..., fill = NULL, FUN, 
        simplify = function(x) do.call(rbind, x)) {
    fill0 <- if (!is.null(fill)) NA
    result <- lapply(
       as.data.frame(t(rollapply(1:nrow(data), ..., fill = fill0, FUN = c))), 
       function(ix) {if (all(is.na(ix))) fill else FUN(data[ix, ])}
    )
    simplify(result)
}

> rollapply(test, 2, FUN = identity, simplify = identity)
$V1
  Name Points
a  bob      4
b jane      9

$V2
  Name Points
b jane      9
c  joe      1

> rollapply(test, 2, FUN = identity, fill = NA, simplify = identity)
$V1
  Name Points
a  bob      4
b jane      9

$V2
  Name Points
b jane      9
c  joe      1

$V3
[1] NA
于 2012-12-07T22:49:31.583 回答