【问题标题】:Modifying vector to contain only ascending elements修改向量以仅包含升序元素
【发布时间】:2021-01-10 01:09:34
【问题描述】:

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

原始数据: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, 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),我的函数将不起作用,因为它只是向前拉一个仍然大于下一个的元素。

【问题讨论】:

    标签: r vector zoo


    【解决方案1】:

    使用nafillcummindata.table 选项

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

    给予

    > nafill(replace(raw, rev(cummin(rev(raw))) != raw, NA), 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
    }
    

    给了

    > f(raw)
     [1]  1  3  3  6  6  6  7  9  9 12
    

    【讨论】:

      【解决方案2】:

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

      # Replace values breaching condition with NA: scrubbed => integer vector
      scrubbed <- replace(raw, rev(cummin(rev(raw))) != 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, rev(cummin(rev(raw))) != raw, NA_integer_),
        method = "constant",
        n = length(raw)
      )$y
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-10
          • 1970-01-01
          • 1970-01-01
          • 2011-03-06
          • 1970-01-01
          • 1970-01-01
          • 2019-12-30
          • 2021-08-01
          相关资源
          最近更新 更多