对于数据框中的给定列,我想构造一个新的向量,每个点由两侧点的平均值组成。然而,对于最后一次观察,它将是倒数第二次。而对于第一次观察,它将是第二次。我写了这个R代码来解决这个问题,但是我反复调用它并且它非常慢。有人可以提供一些有关如何更有效地做到这一点的提示吗?感谢。
x1 <- c(rep('a',100),rep('b',100),rep('c',100))
x2 <- rnorm(300)
x <- data.frame(x1,x2)
names(x) <- c('col1','data1')
a.linear.interpolation <- function(x) {
require(zoo)
require(data.table)
a.dattab <- data.table(x)
setkey(a.dattab,col1)
#replace any NA values using LOCF / NOCB
a.dattab[,data1:=na.locf(data1,na.rm=FALSE),by=list(col1)]
a.dattab[,data1:=na.locf(data1,na.rm=FALSE,fromLast=TRUE),by=list(col1)]
#Adding a within group sequence number and a size of group field to facilitate
#row by row processing
a.dattab[,grpseq:=seq_len(.N),by=list(col1)]
a.dattab[,grpseq_max:=.N,by=list(col1)]
#convert back to data.frame
#data.frame seems faster than data.table for this row by row type processing
a.df <- data.frame(a.dattab)
new.col <- vector(length=nrow(a.df))
for(i in seq(nrow(a.df))){
if(a.df[i,"grpseq"]==1){
new.col[i] <- a.df[i+1,"data1"]
}
else if(a.df[i,"grpseq"]==a.df[i,"grpseq_max"]){
new.col[i] <- a.df[i-1,"data1"]
}
else {
new.col[i] <- (a.df[i-1,"data1"]+a.df[i+1,"data1"])/2
}
}
return(new.col)
}
答案 0 :(得分:1)
除了使用rollmeans
之外,基本R filter
函数也可以执行此类操作。 E.g:
linint <- function(vec) {
c(vec[2], filter(vec, c(0.5, 0, 0.5))[-c(1, length(vec))], vec[length(vec) - 1])
}
x <- c(1,3,6,10,1)
linint(x)
#[1] 3.0 3.5 6.5 3.5 10.0
这很快,在不到一秒的时间内咀嚼10M案件:
x <- rnorm(1e7)
system.time(linint(x))
#user system elapsed
#0.57 0.18 0.75