Reputation: 1673
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
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
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
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
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