根据它们周围的值替换NA

时间:2019-05-15 09:35:51

标签: r for-loop if-statement vector na

比方说,我有一个向量,除每个第5个值外,它都充满了NA,该值可以是两个级别之一:

RNGkind('Mersenne-Twister')
set.seed(42)

x <- NULL
for(i in 1:1000){
  x <- c(x,c(sample(c('Hey', 'Hullo'), 1, rep = F), rep(NA, 4)))
}
x

我想根据周围的NA来填充它们:

"Hullo" NA NA NA NA "Hey": NAs become "Hey" 
"Hullo" NA NA NA NA "Hullo" NAs become "Hullo"
"Hey" NA NA NA NA "Hullo": NAs become "Hullo"
"Hey" NA NA NA NA "Hey": NAs become "Hey"

我提出了一个for循环,该循环迭代地查看每个元素,并根据许多NA语句填充if

for(i in 1:length(x)){
  if(!is.na(x[i])){
     next
   }else{
    if(x[i-1] == 'Hullo' & x[i+4] == 'Hullo' | x[i-1] == 'Hey' & x[i+4] == 'Hullo'){
      x[i:(i+3)] <- 'Hullo'
    }else{
      x[i:(i+3)] <- 'Hey'
    }
  }
}

但这是一种有点怪异的方式,也没有处理向量的尾部,在向量中可能存在NA。理想情况下,NA的最后一组将与最后一组的输出匹配。

如果更容易,那么在两个非NA之间将始终有四个NA

在那里:

  1. 一种更优雅/更快的方法吗?
  2. 一种无需手动完成即可填充向量结尾的方法吗?

编辑: :添加了最后一组NA,并确认非NA总是一致发生间隔(每5个元素)

2 个答案:

答案 0 :(得分:2)

以下是使用tidyr软件包的解决方案:

xres <- tidyr::fill(data = data.frame(x, stringsAsFactors = FALSE), x, .direction = "up")
xres <- tidyr::fill(data = xres, x, .direction = "down")
xres$x

首先填写一个方向,然后填写另一个方向以获取最后一个值

答案 1 :(得分:0)

如果我很了解您的问题,我会尝试使用tidyverse的方法回答。

加载libray:

library(tidyverse)

加载数据:

var1 <- c("Hullo",NA,NA,NA,NA,"Hey")
var2 <- c("Hullo",NA,NA,NA,NA,"Hullo")
var3 <- c("Hey",NA,NA,NA,NA,"Hullo")
var4 <- c("Hey",NA,NA,NA,NA,"Hey")

my_df <- as.data.frame(cbind(var1,var2,var3,var4))

然后使用fill函数:

my_df %>% 
    fill(... = var1:var4,.direction = "up")

这是结果:

   var1  var2  var3 var4
1 Hullo Hullo   Hey  Hey
2   Hey Hullo Hullo  Hey
3   Hey Hullo Hullo  Hey
4   Hey Hullo Hullo  Hey
5   Hey Hullo Hullo  Hey
6   Hey Hullo Hullo  Hey