【问题标题】:Limit na.locf in zoo package在 zoo 包中限制 na.locf
【发布时间】:2019-02-18 06:35:29
【问题描述】:

我想对变量进行最后一次观察,但最多只能进行 2 次观察。也就是说,对于 3 个或更多 NA 的数据间隙,我只会将最后一个观察结果转移到接下来的 2 个观察结果,其余的保留为 NA。

如果我使用zoo::na.locf 执行此操作,maxgap 参数意味着如果间隙大于 2,则不会替换 NA。甚至没有最后 2. 有没有其他选择?

x <- c(NA,3,4,5,6,NA,NA,NA,7,8)
zoo::na.locf(x, maxgap = 2) # Doesn't replace the first 2 NAs of after the 6 as the gap of NA is 3. 
Desired_output <- c(NA,3,4,5,6,6,6,NA,7,8)

【问题讨论】:

    标签: r na zoo locf


    【解决方案1】:

    首先应用na.locf0maxgap = 2 给出x0 并使用data.table 包中的rleid 定义一个分组变量g。对于每个这样的组,使用ave 应用keeper,如果该组全部为 NA,则将其替换为 c(1, 1, NA, ..., NA),否则输出全部 1。乘以 na.locf0(x)

    library(data.table)
    library(zoo)
    
    mg <- 2
    x0 <- na.locf0(x, maxgap = mg)
    g <- rleid(is.na(x0))
    keeper <- function(x) if (all(is.na(x)))  ifelse(seq_along(x) <= mg, 1, NA) else 1
    na.locf0(x) * ave(x0, g, FUN = keeper)
    ## [1] NA  3  4  5  6  6  6 NA  7  8
    

    【讨论】:

    • 谢谢!在这种情况下,是否有可能知道rleidavekeeper 在做什么?
    • rleid 创建一个与其输入长度相同的向量,以便将 1 分配给第一次运行,2 分配给第二次运行,依此类推。答案中描述了keeperave 将第一个参数拆分为由第二个参数定义的组,将指定的函数应用于每个组,然后将它们全部放回原处。使用help 了解更多信息。
    【解决方案2】:

    使用基础 R 的解决方案:

    ave(x, cumsum(!is.na(x)), FUN = function(i){ i[1:pmin(length(i), 3)] <- i[1]; i })
    # [1] NA  3  4  5  6  6  6 NA  7  8
    

    cumsum(!is.na(x)) 将每次运行的NAs 与最近的非NA 值组合在一起。

    function(i){ i[1:pmin(length(i), 3)] &lt;- i[1]; i } 将每个组的前两个NAs 转换为该组的前导非NA 值。

    【讨论】:

    • 不错。一个小的简化可能是将其用作乐趣:function(x) ifelse(seq_along(x) &lt;= 2+1, x[1], NA)
    • @G.Grothendieck,好建议。我原来的功能很笨拙。
    • 虽然我对avepmin 不是很熟悉,但我认为拥有一个内衬非常优雅。你怎么能向后进位? @mt1022 @G.Grothendieck
    • @user3507584, 一种可能的方法是:1)反转向量; 2)用当前答案转换反向向量; 3) 反转转换后的值。
    • @mt1022 感谢您的指导,我想我明白了[使用@G.Grothendieck 对功能的建议]:rev(ave(rev(x), cumsum(!is.na(rev(x))), FUN = function(z) ifelse(seq_along(z) &lt;= 3, z[1], NA)))
    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    相关资源
    最近更新 更多