У меня есть фрейм данных df1. Я хотел бы найти индекс для второго наименьшего значения из этого фрейма данных. С помощью функции which.min мне удалось получить индекс строки для наименьшего значения, но есть ли способ получить индекс для второго наименьшего значения?
> 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
Это мой желаемый результат. Например, в x значение 2 в строке 2 является вторым наименьшим значением. Спасибо.
>df2
x 2
y 2
z 3
Ты можешь сделать :
sapply(df1, function(x) which.max(x == sort(unique(x))[2]))
#x y z
#2 2 3
Или с dplyr
:
library(dplyr)
df1 %>%
summarise(across(.fns = ~which.max(. == sort(unique(.))[2])))
# x y z
# <int> <int> <int>
#1 2 2 3
Вы можете попробовать что-то вроде:
sort(unique(unlist(df1)))[2]
Еще одна базовая версия R с использованием rank
> sapply(df1, function(x) which(rank(unique(x)) == 2))
x y z
2 2 3
Вы можете написать функцию, подобную следующей, используя 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
Тестирование с другими данными:
df2 <- df1
df2$new <- c(1, 1, 1, 2, 3)
which_min(df2, 2)
# x y z new
# 2 2 3 4
Вместо sort
вы можете использовать order
:
sapply(df1, function(x) order(unique(x))[2])
# x y z
# 2 2 3
Или вы можете использовать аргумент index.return
в sort
:
sapply(df1, function(x) sort(unique(x), index.return = TRUE)$ix[2])
# x y z
# 2 2 3
Если мой x будет равен c(1,1,1,2,3), а y и z останутся прежними, возможно ли получить результат второго наименьшего значения для x равным 4?
Проверьте свой вывод на
y
- кажется, что это должно быть1
или3
(или оба?), а не2
.