修改向量以仅包含升序元素

问题描述

我有一个修改的向量,以便它只包含与前一个元素相同或大于前一个元素的元素。该向量表示一种现象,该现象只应增加或保持不变(即按天累积死亡人数),但报告错误会导致元素少于前一个元素。我想通过用以前的元素替换元素来纠正这个问题,直到向量满足上述条件。

原始数据:1 3 3 6 8 10 7 9 15 12

所需的修改数据:1 3 3 6 6 6 7 9 9 12

library(zoo)
raw <- c(1,3,6,8,10,7,9,15,12) 

replace.errors <- function(x){   
x %>% 
replace(diff(x) < 0,NA) %>%
na.locf(na.rm=FALSE)
}

replace.errors(raw)

# [1]  1  3  3  6  8  8  7  9  9 12

如果需要替换一行中的多个顺序元素(8 和 10),我的函数不起作用,因为它只是向前拉动仍然大于下一个元素的元素。

解决方法

使用 this.initialArray = [this.newValue,...this.initialArray]data.tablenafill 选项

cummin

给予

nafill(replace(raw,rev(cummin(rev(raw))) != raw,NA),type = "locf")

按照上述方法的类似想法,您的函数 > nafill(replace(raw,type = "locf") [1] 1 3 3 6 6 6 7 9 9 12 可以定义为

replace.errors

这样

replace.errors <- function(x){   
  x %>%
    replace(rev(cummin(rev(.))) != (.),NA) %>%
    na.locf()
}

另一种选择是定义一个用户函数,如下所示

> replace.errors(raw)
 [1]  1  3  3  6  6  6  7  9  9 12

给出

f <- function(v) {
  for (k in which(c(FALSE,diff(v) < 0))) {
    p <- max(v[v < v[k]])
    v <- replace(v,tail(which(v == p),1):(k - 1),p)
  }
  v
}
,

Base R 使用@ThomasIsCoding 出色的替换逻辑:

# Replace values breaching condition with NA: scrubbed => integer vector
scrubbed <- replace(raw,NA_integer_)

# i) Interpolate constants:
res <- na.omit(scrubbed)[cumsum(!is.na(scrubbed))]

# OR 
# ii) Interpolate constants using approx() 
res <- approx(scrubbed,method = "constant",n = length(scrubbed))$y

或者用一种表达方式:

approx(
  replace(raw,NA_integer_),n = length(raw)
)$y
,

这听起来有点低效,但它可能仍然是最好的选择:

replace_errors <- function(raw) {
  while (is.unsorted(raw)) {
    raw <- raw[c(TRUE,diff(raw) >= 0)]
  }
  raw
}