最后的观察结果在数据框架中?

Tal*_*ili 10 r matrix apply dataframe

我希望对我正在处理的数据集实施"最后一次观察结果",该数据集在结尾处缺少值.

这是一个简单的代码(问题之后):

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))
Run Code Online (Sandbox Code Playgroud)

现在这适用于简单的矢量.但是,如果我在数据框上尝试使用它:

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
Run Code Online (Sandbox Code Playgroud)

它会将我的数据框转换为字符矩阵.

你能想到一种在data.frame上做LOCF的方法,而不用把它变成矩阵吗?(我可以使用循环等来纠正混乱,但是会喜欢更优雅的解决方案)

干杯,

塔尔

Sha*_*ane 21

这已经存在:

library(zoo)
na.locf(data.frame(rep("a",4), 1:4,1:4, c(1,NA,NA,NA)))
Run Code Online (Sandbox Code Playgroud)

  • +1和rseek.org当然会立即将其作为第一个结果点击. (2认同)

小智 9

如果您不想仅为na.locf函数加载像zoo这样的大包,这里有一个简短的解决方案,如果输入向量中有一些前导NA,它也可以工作.

na.locf <- function(x) {
  v <- !is.na(x)
  c(NA, x[v])[cumsum(v)+1]
}
Run Code Online (Sandbox Code Playgroud)


sta*_*007 7

有很多包正是实现了这个功能。(基本功能相同,但附加选项有些差异)

  • 时空::na.locf
  • imputeTS::na_locf
  • 动物园::na.locf
  • xts::na.locf
  • 蒂迪尔::填充

为 @Alex 添加了这些方法的基准:

我使用了 microbenchmark 包和 tsNH4 时间序列,其中有 4552 个观测值。结果如下: 在此输入图像描述

因此,对于这种情况,来自 imputeTS 的 na_locf 是最快的 - 紧随其后的是来自 Zoo 的 na.locf0。其他方法明显慢一些。但请注意,这只是针对一个特定时间序列制定的基准。(添加了您可以针对特定用例进行测试的代码)

结果为图: 在此输入图像描述

如果您想使用自选的时间序列重新创建基准,则代码如下:

library(microbenchmark)
library(imputeTS)
library(zoo)
library(xts)
library(spacetime)
library(tidyr)

# Create a data.frame from tsNH series 
df <- as.data.frame(tsNH4)

res <- microbenchmark(imputeTS::na_locf(tsNH4),
                    zoo::na.locf0(tsNH4),
                    zoo::na.locf(tsNH4), 
                    tidyr::fill(df, everything()), 
                    spacetime::na.locf(tsNH4), 
                    times = 100)
ggplot2::autoplot(res)

plot(res)

# code just to show each methods produces correct output
spacetime::na.locf(tsNH4)
imputeTS::na_locf(tsNH4)
zoo::na.locf(tsNH4)
zoo::na.locf0(tsNH4)
tidyr::fill(df, everything())
Run Code Online (Sandbox Code Playgroud)


Prr*_*dep 7

添加新tidyr::fill()函数以在列中结束最后一次观察以填充NAs:

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
Run Code Online (Sandbox Code Playgroud)