R Return the Index of the Minimum Column for Each Row

R return the index of the minimum column for each row

Your English description suggests you want:

 apply( df, 1, which.min)

But the answer you give is not formatted as a vector and is not the correct answer if the above interpretation is correct. Oh wait, you were expecting rownumbers.

 as.matrix(apply( d, 1, which.min))

[,1]
1 1
2 4
3 3
4 3
5 1
6 1
7 2
8 2
9 4
10 4
11 1
12 3
13 1
14 1
15 3
16 3
17 2
18 3
19 2
20 4

Return Index of Minimum Row for Each Column of Matrix

If we need column wise index use apply with MARGIN=2 and apply the which.min

apply(m1, 2, which.min)
#[1] 3 3

If 1 column at a time is needed:

apply(as.matrix(m1[,1, drop = FALSE]), 2, which.min)

If we check ?Extract, the default usage is

x[i, j, ... , drop = TRUE]

drop - For matrices and arrays. If TRUE the result is coerced to the lowest possible dimension (see the examples). This only works for extracting elements, not for the replacement. See drop for further details.

To avoid getting dimensions dropped, use drop = FALSE

If we need the min values of each row

do.call(pmin, as.data.frame(m1))

Or

apply(m1, 2, min)

Or

library(matrixStats)
rowMins(m1)

data

m1 <- matrix(6:1,nrow=3,ncol=2)

How to find the indexes of minimum value for each row of a dataframe?

We can use apply to loop over the rows (MARGIN =1), compare the elements in the row with min of the row

t(apply(df, 1, function(x) x == min(x)))

-output

#  [,1]  [,2]  [,3]  [,4]
#x TRUE FALSE FALSE TRUE
#y TRUE FALSE TRUE FALSE

Or make it compact with rowMins from matrixStats

library(matrixStats)
df == rowMins(df)
# [,1] [,2] [,3] [,4]
#x TRUE FALSE FALSE TRUE
#y TRUE FALSE TRUE FALSE

Or if we want to stick with base R and use a vectorized option then pmin is another way (after converting the matrix to data.frame)

df == do.call(pmin, as.data.frame(df))

Add column index of min value for each row in new column

The reason for the peculiar output could be that in some row/rows, there are only NAs for the subset of columns, resulting in integer(0)

which.min(c(NA, NA, NA))
#integer(0)

With a example

df1 <- data.frame(col1 = c(1, 2, NA), col2 = c(2, 3, NA), col3 = c(3, 4, NA))

Now, the output is a list

apply(df1, 1, which.min)
#[[1]]
#col1
# 1

#[[2]]
#col1
# 1

#[[3]]
#integer(0)

Instead of which.min, we can wrap with index 1 to coerce the integer(0) to NA

apply(df1, 1, function(x) which.min(x[!is.na(x)])[1])
#[1] 1 1 NA

In the OP's code, it would be

df$indxcol <- apply(df[,28:30],1, function(x) which.min(x[!is.na(x)])[1])

Return Index Row Number of N Minimum/Maximum Value for Each Column of Matrix

To get the index of the highest and lowest values

apply(m1, 2, which.max)
apply(m1, 2, which.min)

If we are interested in 2nd highest, 2nd lowest etc

apply(m1, 2, function(x) order(x)[2])

Or use sort with index.return = TRUE

apply(m1, 2, function(x) sort(x, index.return = TRUE))

and then extract the index of interest

apply(m1, 2, function(x) {i1 <- sort(x, index.return = TRUE)$ix
i1[i1 < 3]
})

If we need the row index

getrowIndexEachCol <- function(mat, n, isMax = TRUE) {
if(!isMax) mat <- -mat
apply(mat, 2, function(x) {i1 <- rank(x)
i1[i1 <= n]
})
}
getrowIndexEachCol(m1, 2)

The difference would be noticed using a different dataset

m2 <- cbind(c(7, 3, 5, 8, 11), c(4, 8, 6, 5, 3))
getrowIndexEachCol(m2, 3)

Find the lowest value and its index until certain row within group

You can use cummin to get minimum value until that row and use match to get the index.

library(dplyr)
a %>%
group_by(subject) %>%
mutate(min = cummin(value),
visit_min = match(min, unique(value)))

# subject visit value min visit_min
# <dbl> <dbl> <dbl> <dbl> <int>
# 1 1 1 100 100 1
# 2 1 2 97 97 2
# 3 1 3 120 97 2
# 4 1 4 84 84 4
# 5 1 5 60 60 5
# 6 1 6 150 60 5
# 7 1 7 150 60 5
# 8 2 1 160 160 1
# 9 2 2 100 100 2
#10 2 3 70 70 3
#11 2 4 40 40 4
#12 2 5 120 40 4

how to find the Min value and index in an R data frame and restructure it into a Tidy data frame

l1 gives the index of minimum value in each column. To get the minimum value use min.

You can create the final dataframe as. :

l1 <- apply(distdf, 2, which.min)
l2 <- apply(distdf, 2, min)

result <- data.frame(City = names(distdf),
NearNeigh = rownames(distdf)[l1],
Dist = l2, row.names = NULL)

result
# City NearNeigh Dist
#1 New.York Chicago 713
#2 Chicago Atlanta 587
#3 Los.Angeles Chicago 1745
#4 Atlanta Chicago 587

R Matrix, get the index of minimum column

You may not need apply here

final_weights <-  (wjs-omega)^2

To get the index of the columns with minimum values, you can use which with arr.ind=TRUE to get the 'row/column' index (a modification of @Bhas comments)

which(final_weights == min(final_weights), arr.ind=TRUE)[,2]

data

set.seed(24)
wjs <- as.data.frame(matrix(sample(0:20, 5*10, replace=TRUE), ncol=5))
set.seed(42)
omega <- as.data.frame(matrix(sample(0:20, 5*10, replace=TRUE), ncol=5))

How to return the index of a column containing minimum value in a dataframe in R

Another approach using @akrun's df1

df1$index_col <- apply(df1[,6:10],1,which.min)+5

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

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


Related Topics



Leave a reply



Submit