在NA和NULL行中回滚xts

时间:2013-07-27 08:55:12

标签: r xts

我需要从n天前的xts对象获取数据行,如果缺少后续行或者使用NA填充,则需要向后跳过。

这是一个示例数据集。

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日。为此,我'通过分配到一个环境来一起攻击那些使用它的东西,但这似乎不是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

您的指导非常感谢。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

最后,我使用findIntervalna.locf在@agstudy的评论中提出了解决方案的变体。

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)
}