【问题标题】:Replacing NAs between two rows with identical values in a specific column用特定列中的相同值替换两行之间的 NA
【发布时间】:2017-08-21 13:59:31
【问题描述】:

我有一个包含多列的数据框,如果 NA 在具有相同编号的两行之间,我想替换一列中的 NA。这是我的数据:

    v1 v2 
    1  2  
    NA 3
    NA 2
    1  1
    NA 7
    NA 2
    3  1

我基本上想从数据帧的开头开始,如果下一个非 NA 与前一个匹配,则在 v1 列中用前一个非 NA 复制 NA。话虽如此,我希望结果是这样的:

    v1 v2 
    1  2  
    1 3
    1 2
    1  1
    NA 7
    NA 2
    3  1        

如您所见,第 2 行和第 3 行被数字“1”替换,因为第 1 行和第 4 行具有相同的数字,但第 5,6 行保持不变,因为第 4 行和第 7 行中的非 na 值不相同。我一直在抽搐,但到目前为止还没有运气。谢谢

【问题讨论】:

    标签: r


    【解决方案1】:

    这是一个使用zoo 包的想法。我们基本上在两个方向上填充 NA,并将这些方向之间不相等的值设置为 NA。

    library(zoo)
    
    ind1 <- na.locf(df$v1, fromLast = TRUE)
    df$v1 <- na.locf(df$v1)
    df$v1[df$v1 != ind1] <- NA
    

    给出,

     v1 v2
    1  1  2
    2  1  3
    3  1  2
    4  1  1
    5 NA  7
    6 NA  2
    7  3  1
    

    【讨论】:

    • 这正是我自己所做的,并在之前的回复中提到了这一点。感谢您以良好的格式提出该回复。顺便说一句,您需要修改最后一行,因为没有 ind2
    • 顺便说一句,当列以 NA 开头或结尾时它不起作用
    • 这是一个非常重要的细节,需要省略。尽管我认为一个简单的规则就足够了,具体取决于您要如何处理它们-最后一行已更改。抱歉打错了
    【解决方案2】:

    这是tidyverse 中使用fill 的类似方法

    library(tidyverse)
    df1 %>%
      mutate(vNew = v1) %>%
      fill(vNew, .direction = 'up') %>%
      fill(v1)  %>%
      mutate(v1 = replace(v1, v1 != vNew, NA)) %>%
      select(-vNew)
    #  v1 v2
    #1  1  2
    #2  1  3
    #3  1  2
    #4  1  1
    #5 NA  7
    #6 NA  2
    #7  3  1
    

    【讨论】:

      【解决方案3】:

      这里是一个base R的解决方案,逻辑和Sotos的差不多:

      replace_na <- function(x){
          f <- function(x) ave(x, cumsum(!is.na(x)), FUN = function(x) x[1])
          y <- f(x)
          yp <- rev(f(rev(x)))
          ifelse(!is.na(y) & y == yp, y, x)
      }
      df$v1 <- replace_na(df$v1)
      

      测试:

      > replace_na(c(1, NA, NA, 1, NA, NA, 3))
      [1]  1  1  1  1 NA NA  3
      

      【讨论】:

        【解决方案4】:

        我可以使用 na.locf 函数来做到这一点。基本上,我使用普通的 na.locf 函数包 zoo 将每个 NA 替换为最新的以前的非 NA 并将数据存储在一个列中。通过使用相同的函数,但将 fromlast=TRUE NA 替换为第一个下一个 nonNA 并将它们存储在另一列中。我检查了这两列,如果这两列的每一行中的结果不匹配,我将它们替换为 NA。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-22
          • 2017-04-22
          • 2016-02-07
          • 1970-01-01
          • 2019-06-27
          相关资源
          最近更新 更多