2017-08-21 31 views
4

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

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

我基本上是想从以前的非NA的数据帧和replcae的NA列V1年初开始,如果接下来的非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

这是一个使用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 
+0

这正是我所做的,并在之前的回复中提到过。感谢您将这种回应以一种好的格式。顺便说一句,你需要修改最后一行,因为没有ind2 – Fatima

+0

顺便说一句,它不起作用,当列开始或结束时不适用 – Fatima

+0

这是一个非常重要的细节忽略。虽然我认为一个简单的规则应该足够取决于你想如何处理它们 - 最后一行改变了。对于输入错误 – Sotos

0

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

1

这里是一个基础R溶液,该逻辑是几乎相同索托斯的一个:

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 
+0

感谢您的回复。那完美的工作 – Fatima

1

这里使用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 
tidyverse类似的方法
相关问题