overwhelmed - 1 year ago 48

R Question

Say I have the following vector:

`y`

[1] 10

[2] 9

[3] 8

[4] 6

[5] 7

[6] -3

[7] -1

Though the position of the minimum can be get using

`which(y==min(y)`

`6`

`4`

Thanks in advance.

Answer Source

Try:

```
first.min <- function(y) {
d <- which(diff(y) > 0)
if (length(d) > 0) d[1] else length(y)
}
first.min(y)
##[1] 4
```

This gives you the position. To get the minimum value:

```
y[first.min(y)]
##[1] 6
```

Suppose you have the case:

```
y <- c(10,9,6,6,7,-3,-1)
```

and you want to find the position of the first `6`

as the position of the first minimum. Then, the above function needs to be modified to:

```
first.min <- function(y) {
d <- diff(y)
p <- which(d > 0)
if (length(p) > 0) p <- p[1] else p <- length(y)
n <- which(d[1:p[1]] < 0)
if (length(n) > 0) n[length(n)]+1 else 1
}
```

Here, we detect the first position of the positive difference as before, but we backtrack to check the position of the last negative difference and return that position plus one. Of course, in this case if we still do want the position of the second `6`

, then we still need the previous version.

To check:

```
## As before
y <- c(10,9,8,6,7,-3,-1)
first.min(y)
##[1] 4
y[first.min(y)]
##[1] 6
## New case
y <- c(10,9,6,6,7,-3,-1)
first.min(y)
##[1] 3
y[first.min(y)]
##[1] 6
## 6 is not a minimum, but -3 is
y <- c(10,9,8,6,6,-3,-1)
first.min(y)
##[1] 6
y[first.min(y)]
##[1] -3
## Edge case where minimum is at end
y <- c(10,9,8,6,5)
first.min(y)
##[1] 5
y[first.min(y)]
##[1] 5
## Edge case where minimum is at last 2 elements, but we want
## the first of these
y <- c(10,9,8,6,6)
first.min(y)
##[1] 4
y[first.min(y)]
##[1] 6
```