我有一个包含多列的数据框,如果它们位于具有相同编号的两行之间,我想在一列中替换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值不相同。我一直在抽筋,但到目前为止还没有运气。感谢
答案 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替换它们。