6

使用 R,我试图从包含多个时间序列的数据帧的开头和结尾修剪 NA 值。我已经使用 for 循环和 zoo 包实现了我的目标,但正如预期的那样,它在大型数据帧上效率极低。

我的数据框看起来像这样,包含 3 列,每个时间序列由它的唯一 ID 标识。在这种情况下,AAA、B 和 CCC。

id   date          value
AAA  2010/01/01    NA
AAA  2010/02/01    34
AAA  2010/03/01    35
AAA  2010/04/01    30
AAA  2010/05/01    NA
AAA  2010/06/01    28
B    2010/01/01    NA
B    2010/02/01    0
B    2010/03/01    1
B    2010/04/01    2
B    2010/05/01    3
B    2010/06/01    NA
B    2010/07/01    NA
B    2010/07/01    NA
CCC  2010/01/01    0
CCC  2010/02/01    400
CCC  2010/03/01    300
CCC  2010/04/01    200
CCC  2010/05/01    NA

我想知道,如何有效地从每个时间序列的开始和结束删除 NA 值,在这种情况下为 AAA、B 和 CCC。所以它应该看起来像这样。

id   date          value
AAA  2010/02/01    34
AAA  2010/03/01    35
AAA  2010/04/01    30
AAA  2010/05/01    NA
AAA  2010/06/01    28
B    2010/02/01    0
B    2010/03/01    1
B    2010/04/01    2
B    2010/05/01    3
CCC  2010/01/01    0
CCC  2010/02/01    400
CCC  2010/03/01    300
CCC  2010/04/01    200
4

2 回答 2

7

我会这样做,这应该非常快:

require(data.table)
DT = as.data.table(your data)   # please provide something pastable

DT2 = DT[!is.na(value)]
setkey(DT,id,date)
setkey(DT2,id,date)
tokeep = DT2[DT,!is.na(value),rolltolast=TRUE,mult="last"]
DT = DT[tokeep]

这是通过在每个组内滚动流行的非 NA 来实现的,但不会超过最后一个。

mult="last"是可选的。如果使用 v1.8.0(在 CRAN 上),它应该会加快速度。对有和没有它的时间感兴趣。默认情况下data.table加入组 ( mult="all"),但在这种情况下,我们将加入键的所有列,并且我们知道键是唯一的;即,没有重复键。在 v1.8.1(开发版)中,无需了解这一点,它会更加照顾您。

于 2012-05-30T09:25:14.313 回答
0

如果您的数据在数据框中data

fun <- function(x)
{
    x$value[is.na(x$value)] <- "NA"
    tmp <- rle(x$value)
    values <- tmp$values
    lengths <- tmp$lengths
    n <- length(values)

    nr <- nrow(x)
    id <- c()
    if(values[1] == "NA") id <- c(id, 1:lengths[1])
    if(values[n] == "NA") id <- c(id, (nr-lengths[n]+1):nr)
    if(length(id) == 0)return(x)
    x[-id,]
}

do.call(rbind,
        by(data, INDICES=data$id,
           FUN=fun))

我猜这不是最优雅的解决方案。在这篇文章的心情。

于 2012-05-30T08:52:02.260 回答