使用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
答案 0 :(得分: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(在开发中),没有必要知道这一点,它会照顾你更多。
答案 1 :(得分: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))
我猜不是最优雅的解决方案。心情this post。