简体   繁体   中英

R: pmax() function to ignore NA's?

I built this custom "winsorize" function that does what it should, unless there are NA's in the data.

How it works:

winsor1 <- function(x, probability){

  numWin <- ceiling(length(x)*probability)

  # Replace first lower, then upper
  x <- pmax(x, sort(x)[numWin+1])
  x <- pmin(x, sort(x)[length(x)-numWin])

  return(x)
}

x <- 0:10

winsor1(x, probability=0.01)
[1] 1  1  2  3  4  5  6  7  8  9  9

So it replaces the top (and bottom) 1% of the data (rounded up to the next value, since there are only 11 values in the example). If there are, eg, 250 values then the bottom 3 and top 3 values would be replaced by the bottom 4th and top 4th respectively.

The whole thing breaks down when there are NA's in the data, causing an error. However, if I set na.rm = TRUE in the pmax() and pmin() then the NA's themselves are replaced by the bottom value.

x[5] <- NA

winsor1(x, probability=0.01)
[1] 1  1  2  3  1  5  6  7  8  9  9

What can I do so that the NA's are preserved but do not cause an error? This is the output I want for the last line:

winsor1(x, probability=0.01)
[1] 1  1  2  3  NA  5  6  7  8  9  9

The issue is with sort as it removes the NA by default or else we have to specify na.last = TRUE which may also not be the case we need. One option is order

winsor1 <- function(x, probability){

  numWin <- ceiling(length(x)*probability)

  # Replace first lower, then upper
  x1 <- x[order(x)]
  x <- pmax(x, x1[numWin+1])
  x1 <- x1[order(x1)]
  x <- pmin(x, x1[length(x)-numWin], na.rm = TRUE)

  return(x)
}

-testing

x <- 0:10
winsor1(x, probability=0.01)
#[1] 1 1 2 3 4 5 6 7 8 9 9

x[5] <- NA 
winsor1(x, probability=0.01)
#[1]  1  1  2  3 NA  5  6  7  8  9 10

or with na.last in sort

winsor1 <- function(x, probability){

  numWin <- ceiling(length(x)*probability)

  # Replace first lower, then upper
  x <- pmax(x, sort(x, na.last = TRUE)[numWin+1])
  x <- pmin(x, sort(x, na.last = TRUE)[length(x)-numWin], na.rm = TRUE)

  return(x)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM