【问题标题】:Na fill after a specific value特定值后的 Na 填充
【发布时间】:2021-12-12 14:39:47
【问题描述】:

我想在 1 之后使用 NA.fill,但在 -1 之后保留 NA。有没有简单的解决方案?

Old New
1 1
NA 1
NA 1
NA 1
-1 -1
NA NA
NA NA
1 1
NA 1
NA 1

可重现的示例数据

dat <- read.table(text = "
Old New
1   1
NA  1
NA  1
NA  1
-1  -1
NA  NA
NA  NA
1   1
NA  1
NA  1", header = TRUE)

编辑:我的列中只有 1 和 -1。谢谢大家,答案非常有帮助。我的“新”专栏现在正是我想要的。

【问题讨论】:

标签: r na fill


【解决方案1】:

cumsum

df$Old[as.logical(cumsum(replace(df$Old, is.na(df$Old), 0)))] <- 1

【讨论】:

  • 假设数据中只有 1 和 -1,这很好。
  • @zx8754 更进一步,它假设 1 和 -1 是交替的。
  • 哎呀,也许值得用警告/假设进行编辑。
【解决方案2】:

你可以使用循环

x = c(1,NA,NA,NA,-1,NA,NA,1,NA,NA)
for (i in seq_along(x)[-1]) {
  if (!is.na(x[i-1]) & x[i-1] == 1 & is.na(x[i])) x[i] = 1
}
# [1]  1  1  1  1 -1 NA NA  1  1  1

【讨论】:

    【解决方案3】:

    这是一种使用rle 的方法,请给予或接受。

    r <- rle(ifelse(is.na(dat$Old), -Inf, dat$Old))
    r$values[is.infinite(r$values)] <- NA_integer_
    r
    # Run Length Encoding
    #   lengths: int [1:6] 1 3 1 2 1 2
    #   values : num [1:6] 1 NA -1 NA 1 NA
    
    ind <- is.na(r$values[-1]) & r$values[-length(r$values)] == 1
    ind
    # [1]  TRUE FALSE FALSE FALSE  TRUE
    r$values[c(FALSE, ind)] <- r$values[c(ind, FALSE)]
    inverse.rle(r)
    #  [1]  1  1  1  1 -1 NA NA  1  1  1
    

    注意事项:

    • rle 将所有缺失值(即NA)视为不相等,这违背了我们对游程编码的预期用途;我通过首先将NA 转换为-Inf 来解决这个问题(有点随意,我认为极不可能出现在真实数据中),运行rle,然后转换回NA
    • is.na(r$values[-1]) &amp; r$values[-length(r$values)] == 1判断一个值为NA,前一个值为1
    • 我们使用该值(如ind)来确定要替换哪些值(c(F, ind))以及用哪些值替换它们(c(ind, F));
    • inverse.rle 做了它应该做的事情:重新生成向量,但现在将 1-following-NA 值更改为 1,没有其他更改

    如果逻辑改为“填充NA,除非先前的值不是-1”(如果还有非1值应该填充)通过更改ind计算从== 1!= -1

    【讨论】:

    • 这是假设我们想用 1 填充 NA,而不是第一个非 na 值。顺便说一句,我喜欢 rle 解决方案!
    • 好点,已补救。谢谢@zx8754
    【解决方案4】:

    使用data.table

    library(data.table)
    
    setDT(dat)[, x := fifelse(is.na(Old) & head(Old, 1) == 1, head(Old, 1), Old), 
              by = cumsum(!is.na(Old)) ]
    
    df
    #     Old New  x
    #  1:   1   1  1
    #  2:  NA   1  1
    #  3:  NA   1  1
    #  4:  NA   1  1
    #  5:  -1  -1 -1
    #  6:  NA  NA NA
    #  7:  NA  NA NA
    #  8:   1   1  1
    #  9:  NA   1  1
    # 10:  NA   1  1
    

    【讨论】:

      【解决方案5】:

      您可以通过fillifelse 来做到这一点

      library(tidyverse)
      dat <- structure(list(Old = c(1L, NA, NA, NA, -1L, NA, NA, 1L, NA, NA
      )), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
      )) 
      
      dat %>% 
      mutate(New = Old) %>% 
      fill(New) %>% 
      mutate(New = ifelse(New == -1, Old, New)) %>% 
      select(Old, New)
      

      结果:

      # A tibble: 10 x 2
           Old   New
         <int> <int>
       1     1     1
       2    NA     1
       3    NA     1
       4    NA     1
       5    -1    -1
       6    NA    NA
       7    NA    NA
       8     1     1
       9    NA     1
      10    NA     1
      

      我认为 SO this question 也可能会有所帮助。

      【讨论】:

        【解决方案6】:

        类似于@Otto Kässi 使用zoo::na.locf 的逻辑-

        transform(dat, New = zoo::na.locf(Old)) |>
          transform(New = ifelse(New == -1, Old, New))
        
        #   Old New
        #1    1   1
        #2   NA   1
        #3   NA   1
        #4   NA   1
        #5   -1  -1
        #6   NA  NA
        #7   NA  NA
        #8    1   1
        #9   NA   1
        #10  NA   1
        

        【讨论】:

          【解决方案7】:

          purrr::reduce:

          library(tidyverse)
          
          reduce(2:nrow(dat), function(x,y) {
            if (is.na(x$Old[y]) & !is.na(x$Old[y-1]) & x$Old[y-1] == 1) x$Old[y] <- 1; x},
            .init=dat)
          #>    Old New
          #> 1    1   1
          #> 2    1   1
          #> 3    1   1
          #> 4    1   1
          #> 5   -1  -1
          #> 6   NA  NA
          #> 7   NA  NA
          #> 8    1   1
          #> 9    1   1
          #> 10   1   1
          

          【讨论】:

            猜你喜欢
            • 2020-06-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-21
            • 1970-01-01
            • 2021-08-03
            • 2022-08-18
            • 2017-12-05
            相关资源
            最近更新 更多