Dominique Makowski
Dominique Makowski

Reputation: 1673

Find closest value in list in R

I have a list of labels associated with values. I would like, for a value x, to find the label corresponding to the closest (but inferior) value of the list.

I found a way of doing it, but it looks quite messy and complicated...

mylist <- list("A"=0.02,
               "B"=0.13,
               "C"=0.26)

x = 0.14 # B

df <- as.data.frame(t(as.data.frame(mylist)))
df <- tibble::rownames_to_column(df, "labels")
df$V2 <- x > df$V1
maxi <- max(df[df$V2 == TRUE,]$V1)
label <- df[df$V1 == maxi,]$labels

Is there another, neat way of doing it?

Upvotes: 1

Views: 1686

Answers (4)

moodymudskipper
moodymudskipper

Reputation: 47320

I recommend other more compact solutions, but here's a tidy version of what you were trying to accomplish :

library(tidyverse)
mylist %>%
  as_tibble %>%
  gather %>%
  filter(value < x) %>%
  summarize(key=key[which.max(value)]) %>%
  pull(key)

# [1] "B"

Upvotes: 1

Onyambu
Onyambu

Reputation: 79228

You can decide to sort the vector then take the previous value:

a=sort(c(x=x,unlist(mylist)))
names(a[which(names(a)=="x")-1])
[1] "B"

Upvotes: 0

Ronak Shah
Ronak Shah

Reputation: 388982

We subtract value of x with every value of mylist, filter out the ones where difference is greater than 0 and select the names of the minimum difference.

new <- x - unlist(mylist) 
names(which.min(new[new > 0]))
#[1] "B"

Or a one -liner, where we filter only those values which are less than x and select the max from it.

names(which.max(sapply(mylist, function(i) i[(x - i) > 0])))
#[1] "B"

Upvotes: 1

Roland
Roland

Reputation: 132706

Your list should be a vector:

myvector <- c("A"=0.02,
              "B"=0.13,
              "C"=0.26)
#sort
myvector <- sort(myvector, decreasing = TRUE)
#test
test <- x > myvector
#name of element with first TRUE in test
res <- if(any(test)) names(which.max(test)) else NA_character_
#[1] "B"

Upvotes: 0

Related Questions