R 用特定列中相同的值替换两行之间的NAs
我有一个具有多列的数据帧,如果NAs位于两行之间且编号相同,我希望在一列中替换NAs。以下是我的数据:R 用特定列中相同的值替换两行之间的NAs,r,R,我有一个具有多列的数据帧,如果NAs位于两行之间且编号相同,我希望在一列中替换NAs。以下是我的数据: v1 v2 1 2 NA 3 NA 2 1 1 NA 7 NA 2 3 1 我基本上想从数据帧的开头开始,如果下一个非NA与上一个匹配,则用上一个非NA替换v1列中的NAs。话虽如此,我希望结果如下: v1 v2 1 2 1 3 1 2 1 1 NA 7
v1 v2
1 2
NA 3
NA 2
1 1
NA 7
NA 2
3 1
我基本上想从数据帧的开头开始,如果下一个非NA与上一个匹配,则用上一个非NA替换v1列中的NAs。话虽如此,我希望结果如下:
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值不相同。我一直在胡闹,但到目前为止运气不好。谢谢这里有一个使用
zoo
软件包的想法。我们基本上是在两个方向上填充NAs,并将NA设置为这些方向之间不相等的值
library(zoo)
ind1 <- na.locf(df$v1, fromLast = TRUE)
df$v1 <- na.locf(df$v1)
df$v1[df$v1 != ind1] <- NA
我可以使用na.locf函数这样做。基本上,我使用普通的na.locf函数包zoo用最新的非na替换每个na,并将数据存储在一列中。通过使用相同的函数,但修复fromlast=TRUE,NAs将替换为第一个下一个nonNA,并将其存储在另一列中。我检查了这两列,如果这两列的每行结果不匹配,我将它们替换为NA 这是一个基本的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)
在
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
这正是我自己所做的,并且在之前的回复中提到了这一点。谢谢你用一个好的格式来回复。顺便说一句,您需要修改最后一行,因为没有ind2BTW。当列以NAThat开头或结尾时,它不起作用。这是一个非常重要的细节,需要省略。尽管我认为一个简单的规则就足够了,这取决于你想要如何处理它们——最后一行已经改变了。对不起,打错了
> replace_na(c(1, NA, NA, 1, NA, NA, 3))
[1] 1 1 1 1 NA NA 3
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