【问题标题】:Replace NAs based on values surrounding them根据周围的值替换 NA
【发布时间】:2019-10-02 09:45:18
【问题描述】:

假设我有一个充满 NAs 的向量,除了每 5 个值,它可能是两个级别之一:

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

我想根据周围的情况填写NAs:

"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 循环,它迭代地查看每个元素并根据大量 if 语句填充 NAs:

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 将匹配最后一组的输出。

如果它更容易,在两个非NAs 之间总会有四个NAs。

有吗:

  1. 更优雅/更快的方式来做到这一点?
  2. 一种无需手动填充矢量末尾的方法?

编辑: 添加了最后一组 NAs 并确认非NAs 总是以一致的时间间隔出现(每 5 个元素)

【问题讨论】:

  • 嗨 Ronak: 1. 最后一个值为 NA,最后一组的输出将与前一组的输出匹配。 2. 是的,两个非 NA 之间总是有 4 个 NA。
  • 嗯,不完全是,有一些不匹配:如果你运行 for 循环,然后你的:x1

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


【解决方案1】:

如果我很好地理解了你的问题,我会尝试使用tidyverse 的方法来回答。

加载库:

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

【讨论】:

    【解决方案2】:

    这是使用tidyr 包的解决方案:

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

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

    【讨论】:

    • 很高兴它有帮助!我认为在 base R 中可能有一个解决方案,也许有人会发布它。
    猜你喜欢
    • 1970-01-01
    • 2019-10-17
    • 2014-02-16
    • 2023-02-13
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    • 2018-07-06
    • 1970-01-01
    相关资源
    最近更新 更多