在特定列中使用相同值替换两行之间的NAs

时间:2017-08-21 13:59:31

标签: r

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

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

我基本上想从数据帧的开头开始,如果下一个非NA与前一个非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值不相同。我一直在抽筋,但到目前为止还没有运气。感谢

4 个答案:

答案 0 :(得分:4)

这是使用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

答案 1 :(得分:1)

这是一个基础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

答案 2 :(得分:1)

以下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 :(得分:0)

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