rnorouzian
rnorouzian

Reputation: 7517

Extract vector names conditionally in R

I'm trying to get the names of the elements in a vector with some priorities.

If there is any element with value "integer", get the name of the first of such elements (in the example below, year)

But if there is no element with value "integer", then do the same thing with any element with value "numeric".

I have tried the following without success (this is a toy example a functional answer is appreciated):

cl <- c(group = "character", degree = "numeric", year = "integer", zoo = "integer")

names(cl[cl == "integer" || cl == "numeric"])[1]

desired.output = "year"

Upvotes: 2

Views: 201

Answers (3)

akrun
akrun

Reputation: 887108

As it is a fixed match, we can use %in%

names(sort(cl[cl %in% c('integer', 'numeric')]))[1]
#[1] "year"

Or convert to factor with levels specified

names(sort(factor(cl, c('integer', 'numeric'))))[1]
#[1] "year"

Or with match

names(cl)[na.omit(match(c('integer', 'numeric'), cl))[1]]
#[1] "year"

Upvotes: 1

jay.sf
jay.sf

Reputation: 72803

Using grep.

names(sort(cl[grep("integer|numeric", cl)])[1])
# [1] "year"

Upvotes: 0

MattB
MattB

Reputation: 671

You're close, but there are two issues with your approach so far:

  1. The || operator only works with one element; since you're looking over more than one you would want | instead. See ?`||` for more details.
  2. Your approach would treat "integer" and "numeric" equally, rather than prioritising numeric as you would prefer.

One way of doing it would be:

Coalesce2 <- function(x, y) if(is.na(x))  y  else  x
Coalesce2(cl[cl == "integer"][1], cl[cl == "numeric"][1])

NB. The only reason I've made a new coalesce function here rather than using dplyr's is that that doesn't preserve names in the way I think you want.

Upvotes: 1

Related Questions