简体   繁体   中英

Finding the index for 2nd Min value in a data frame

I have a data frame df1. I would like to find the index for the second smallest value from this dataframe. With the function which.min I was able to get the row index for the smallest value but is there a way to get the index for the second smallest value?

> df1
structure(list(x = c(1, 2, 3, 4, 3), y = c(2, 3, 2, 4, 6), z = c(1, 
4, 2, 3, 11)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", 
"data.frame"))


 >df1
 x    y    z
 1    2    1
 2    3    4
 3    2    2
 4    4    3
 3    6   11

This is my desired output. For example, in x, the value 2 in row 2 is the second smallest value. Thank you.

>df2
x    2
y    2
z    3

You can do:

sapply(df1, function(x) which.max(x == sort(unique(x))[2]))

#x y z 
#2 2 3 

Or with dplyr :

library(dplyr)
df1 %>%
  summarise(across(.fns = ~which.max(. == sort(unique(.))[2])))

#      x     y     z
#  <int> <int> <int>
#1     2     2     3

Another base R version using rank

> sapply(df1, function(x) which(rank(unique(x)) == 2))
x y z
2 2 3

Updated answer

You can write a function like the following, using factor :

which_min <- function(x, pos) {
  sapply(x, function(y) {
    which(as.numeric(factor(y, sort(unique(y)))) == pos)[1]
  })
}

which_min(df1, 2)
# x y z 
# 2 2 3 

Testing it out with other data:

df2 <- df1
df2$new <- c(1, 1, 1, 2, 3)
which_min(df2, 2)
#   x   y   z new 
#   2   2   3   4 

Original answer

Instead of sort , you can use order :

sapply(df1, function(x) order(unique(x))[2])
# x y z 
# 2 2 3

Or you can make use of the index.return argument in sort :

sapply(df1, function(x) sort(unique(x), index.return = TRUE)$ix[2])
# x y z 
# 2 2 3

You could try something like:

sort(unique(unlist(df1)))[2]

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