A function to find the “Penultimax”

Penulti-what?  Let me explain: Today I had to iteratively go through each row of a donor history dataset and compare a donor’s maximum yearly donation total to the second highest yearly donation total.  In even more concrete terms, for each row I had to compare the maximum value across 5 columns against the next highest number.  This seemed to be a rather unique task, and so I had to make an R function to help carry it out.

So, I named the function “penultimax”, to honour the idea that it’s finding the second highest, or second max.  It works pretty simply, really just by removing the maximum value from the input vector, and returning the maximum of the new vector, if it’s there at all.  Following is the code for it (notice that it draws on an earlier function that I made, called safe.max, that returns an NA when it can’t find a maximum, instead of an error):

Did I miss something out there that’s simpler than what I wrote?

About these ads

8 thoughts on “A function to find the “Penultimax”

  1. There are a couple of convenient commands that might make this simpler – na.omit and which.max.

    penultimax = function(invector)
    {
       # just check its got more than two numbers
       invector=na.omit(invector)
       if (length(invector) < 2 | !(is.numeric(x))
    return(NA)
    # which.max is clear
    newvector = invector[-which.max]
       return(max(new vector))

    }

  2. The only problem with the other answers occurs when you have duplicate values for the maximum. Also, there is no reason to use

    na.omit(x)

    Created by Pretty R at inside-R.org since

    sort(x)

    Created by Pretty R at inside-R.org will remove the missing values.

    So here is a function that should give you what you want (and return NA in all the places the above functions do)

    penultimax <- function(x) {
      x <- sort(x, decreasing=TRUE)
      return(x[!(x %in% x)][1])
    }

    Created by Pretty R at inside-R.org

    • Could also try taking unique values before sorting, which might save some time if you use it on large data sets (warning: not tested):
      penultimax <- function(x){
      x 1) x[2]
      }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s