虚拟数据集是:
data <- data.frame(
group = c(1,1,1,1,1,2),
dates = as.Date(c("2005-01-01", "2006-05-01", "2007-05-01","2004-08-01",
"2005-03-01","2010-02-01")),
value = c(10,20,NA,40,NA,5)
)
对于每个group
,缺失值需要使用与相同组中最近日期对应的非缺失值填充。如果出现平局,请选择任何一个。
我正在使用dplyr
。来自birk的which.closest
但它需要一个向量和一个值。如何在不写循环的情况下在向量内查找。即使有SQL
解决方案,也可以。
任何指向解决方案的指针?
可能类似于:value = value[match(which.closest(dates,THISdate) & !is.na(value))]
不确定如何指定Thisdate
。
编辑:期望值向量应如下所示:
value = c(10,20,20,40,10,5)
答案 0 :(得分:1)
使用类包中的knn1
(最近邻居)(不需要安装它)和dplyr定义na.knn1
函数,它替换{{}中的每个NA值。 1}}非NA x
值最近x
。
time
,并提供:
library(class)
na.knn1 <- function(x, time) {
is_na <- is.na(x)
if (sum(is_na) == 0 || all(is_na)) return(x)
train <- matrix(time[!is_na])
test <- matrix(time[is_na])
cl <- x[!is_na]
x[is_na] <- as.numeric(as.character(knn1(train, test, cl)))
x
}
data %>% mutate(value = na.knn1(value, dates))
如果打算按组执行此操作,请添加适当的 group dates value
1 1 2005-01-01 10
2 1 2006-05-01 20
3 1 2007-05-01 20
4 1 2004-08-01 40
5 1 2005-03-01 10
6 2 2010-02-01 5
。
答案 1 :(得分:0)
你可以尝试使用sapply
来查找自`which.closest只取一个值的x
参数以来最接近的值。
首先创建一个vect
,其中没有值的日期会替换为NA
,并在which.closest
函数中使用它。
library(birk)
vect=replace(data$dates,which(is.na(data$value)),NA)
transform(data,value=value[sapply(dates,which.closest,vec=vect)])
group dates value
1 1 2005-01-01 10
2 1 2006-05-01 20
3 1 2007-05-01 20
4 1 2004-08-01 40
5 1 2005-03-01 10
6 2 2010-02-01 5
如果which.closest
采用向量,那么就不需要sapply
。但事实并非如此
使用dplyr
包:
library(birk)
library(dplyr)
data%>%mutate(vect=`is.na<-`(dates,is.na(value)),
value=value[sapply(dates,which.closest,vect)])%>%
select(-vect)