2

NA我需要从 n 天后的 xts 对象中获取数据行,如果 n 天后的行不存在或填充有s ,则向后跳过。

这是一个示例数据集。

require(xts)
set.seed(1)

ddf <- data.frame('1m' = rnorm(25), '3m' = rnorm(25))
xxd <- xts(ddf, seq(as.Date('2013-07-27'), length.out = 25, by='day'))
xxd[sample(1:25, 8), ] <- NA
xxd <- xxd[-sample(1:25, 3), ]

xts对象xxd既没有 8 月 19 日也没有 8 月 18 日,8 月 17 日就是全部NA,所以我想在 8 月 16 日返回。为此,我将通过分配给环境使用的东西拼凑在一起,但这没有t 看起来非常R(或非常实用) - 这样做的正确方法是什么?

rewindX <- function(Xts, dayRew = 1)
{
    flipDates <- function(dayRew)
    {
        assign('newX', Xts[index(last(Xts)) - dayRew], envir = outXenv)
        if(!length(which(!is.na(outXenv$newX)))) 
        {
            dayRew <- dayRew + 1
            flipDates(dayRew)
        }
    }
    outXenv <- new.env(parent = .GlobalEnv)
    flipDates(dayRew)
    return(outXenv$newX)
}

所以要倒带,我给出rewindX(xxd, 1)并获得一行。

这里有两个例子:

> rewindX(xxd, 1)
                 X1m        X3m
2013-08-16 0.9189774 -0.7074952
> rewindX(xxd, 10)
                  X1m        X3m
2013-08-08 -0.6212406 -0.0593134

非常感谢您的指导。

4

2 回答 2

2

你正在寻找na.locf

用它之前的最近的非 NA 替换每个 NA 的通用函数。

所以在你的例子中:

set.seed(1)
ddf <- data.frame('1m' = rnorm(25), '3m' = rnorm(25))
xxd <- xts(ddf, seq(as.Date('2013-07-27'), length.out = 25, by='day'))
xxd[sample(1:25, 8), ] <- NA
xxc <- na.locf(xxd)
xxc["2013-08-16/"]                ## 19 to 17  are equal to 16
                  X1m        X3m
2013-08-16  0.1437715 -0.7767766
2013-08-17  0.1437715 -0.7767766
2013-08-18  0.1437715 -0.7767766
2013-08-19  0.1437715 -0.7767766
2013-08-20 -0.7970895  0.5767188
于 2013-07-27T09:57:12.250 回答
0

最后,我选择了@agstudy 在评论中建议的解决方案的变体,使用findIntervaland na.locf

require(xts)

xd <- xts(rnorm(20), order.by = seq(Sys.Date(), by = 'week', length.out=20))

# objective: rewind back n days, filling in NAs with prior observation
# rewind an xts object by n days
rewindX_fi <- function(Xts, dayRew=1, fillNA = TRUE, last = TRUE, oldDates = TRUE){
    # rewinds an Xts object by dayRew days
    lastFlip <- function(X) {
        if(last) {
            last(X)
        } else X 
    }
    stopifnot(is.xts(Xts))
    newDates <- index(Xts) - dayRew
    rewindRows <- findInterval(newDates, index(Xts))
    Xts_rew <- xts(rep(NA, nrow(Xts)), 
                   order.by = if(oldDates) index(Xts) else newDates)
    nonZeros <- rewindRows[rewindRows > 0]
    Xts_rew[rewindRows > 0,] <- if(fillNA) {
        na.locf(Xts, na.rm = FALSE)[nonZeros,]
    } else {
        Xts_rew <- Xts[nonZeros, ]
    }
    lastFlip(Xts_rew)
}
于 2013-10-11T04:31:21.397 回答