我希望为我正在处理的数据集实施“最后一次观察结果”,该数据集在结尾处缺少值。
这是一个简单的代码(问题之后):
LOCF <- function(x)
{
# Last Observation Carried Forward (for a left to right series)
LOCF <- max(which(!is.na(x))) # the location of the Last Observation to Carry Forward
x[LOCF:length(x)] <- x[LOCF]
return(x)
}
# example:
LOCF(c(1,2,3,4,NA,NA))
LOCF(c(1,NA,3,4,NA,NA))
现在这适用于简单的矢量。但是,如果我尝试在数据框上使用它:
a <- data.frame(rep("a",4), 1:4,1:4, c(1,NA,NA,NA))
a
t(apply(a, 1, LOCF)) # will make a mess
它会将我的数据框变成字符矩阵。
你能想到一种在data.frame上做LOCF的方法,而不是把它变成矩阵吗? (我可以使用循环等来纠正混乱,但是会喜欢更优雅的解决方案)
干杯,
塔尔
答案 0 :(得分:20)
这已经存在:
library(zoo)
na.locf(data.frame(rep("a",4), 1:4,1:4, c(1,NA,NA,NA)))
答案 1 :(得分:6)
如果您不想为na.locf函数加载像zoo这样的大包,这里有一个简短的解决方案,如果输入向量中有一些主要的NA,它也可以工作。
na.locf <- function(x) {
v <- !is.na(x)
c(NA, x[v])[cumsum(v)+1]
}
答案 2 :(得分:5)
添加新的tidyr::fill()
函数,用于结束列中的最后一次观察以填充NA
s:
a <- data.frame(col1 = rep("a",4), col2 = 1:4,
col3 = 1:4, col4 = c(1,NA,NA,NA))
a
# col1 col2 col3 col4
# 1 a 1 1 1
# 2 a 2 2 NA
# 3 a 3 3 NA
# 4 a 4 4 NA
a %>% tidyr::fill(col4)
# col1 col2 col3 col4
# 1 a 1 1 1
# 2 a 2 2 1
# 3 a 3 3 1
# 4 a 4 4 1
答案 3 :(得分:4)
有许多软件包正好实现了这一功能。 (具有相同的基本功能,但在其他选项中存在一些差异)
答案 4 :(得分:2)
这个问题很老但是对后人来说......最好的解决方案是使用带有roll = T的data.table包。
答案 5 :(得分:0)
我最后用循环来解决这个问题:
fillInTheBlanks <- function(S) {
L <- !is.na(S)
c(S[L][1], S[L])[cumsum(L)+1]
}
LOCF.DF <- function(xx)
{
# won't work well if the first observation is NA
orig.class <- lapply(xx, class)
new.xx <- data.frame(t( apply(xx,1, fillInTheBlanks) ))
for(i in seq_along(orig.class))
{
if(orig.class[[i]] == "factor") new.xx[,i] <- as.factor(new.xx[,i])
if(orig.class[[i]] == "numeric") new.xx[,i] <- as.numeric(new.xx[,i])
if(orig.class[[i]] == "integer") new.xx[,i] <- as.integer(new.xx[,i])
}
#t(na.locf(t(a)))
return(new.xx)
}
a <- data.frame(rep("a",4), 1:4,1:4, c(1,NA,NA,NA))
LOCF.DF(a)
答案 6 :(得分:0)
您可以使用apply()
代替lapply()
,然后将结果列表转换为data.frame
。
LOCF <- function(x) {
# Last Observation Carried Forward (for a left to right series)
LOCF <- max(which(!is.na(x))) # the location of the Last Observation to Carry Forward
x[LOCF:length(x)] <- x[LOCF]
return(x)
}
a <- data.frame(rep("a",4), 1:4, 1:4, c(1, NA, NA, NA))
a
data.frame(lapply(a, LOCF))