R: Get the min/max of each item of a vector compared to single value
I'm guessing you're looking for pmin
/pmax
:
> pmin(a$v, n)
[1] 3 1 4
> pmax(a$v, n)
[1] 4 4 5
Creating a loop in R to find a minimum value of a vector by using comparison operators (, , ==, etc.)
This should do the trick. First create a variable called "low" with a high value (as @alistaire suggested). Then, loop through your values of aVector. At each value, check if the value is less than low. If it is, update low to that value.
set.seed(42)
aVector <- sample(0:100, 100, replace=FALSE)
low <- Inf # initialize with high value
for (i in aVector) {
if(i < low){
low <- i
}
}
print(low)
# Confirm we got correct answer
min(aVector)
Fastest way to find second (third...) highest/lowest value in vector or column
Rfast has a function called nth_element that does exactly what you ask.
Further the methods discussed above that are based on partial sort, don't support finding the k smallest values
Update (28/FEB/21) package kit offers a faster implementation (topn) see https://stackoverflow.com/a/66367996/4729755, https://stackoverflow.com/a/53146559/4729755
Disclaimer: An issue appears to occur when dealing with integers which can by bypassed by using as.numeric (e.g. Rfast::nth(as.numeric(1:10), 2)), and will be addressed in the next update of Rfast.
Rfast::nth(x, 5, descending = T)
Will return the 5th largest element of x, while
Rfast::nth(x, 5, descending = F)
Will return the 5th smallest element of x
Benchmarks below against most popular answers.
For 10 thousand numbers:
N = 10000
x = rnorm(N)
maxN <- function(x, N=2){
len <- length(x)
if(N>len){
warning('N greater than length(x). Setting N=length(x)')
N <- length(x)
}
sort(x,partial=len-N+1)[len-N+1]
}
microbenchmark::microbenchmark(
Rfast = Rfast::nth(x,5,descending = T),
maxn = maxN(x,5),
order = x[order(x, decreasing = T)[5]])
Unit: microseconds
expr min lq mean median uq max neval
Rfast 160.364 179.607 202.8024 194.575 210.1830 351.517 100
maxN 396.419 423.360 559.2707 446.452 487.0775 4949.452 100
order 1288.466 1343.417 1746.7627 1433.221 1500.7865 13768.148 100
For 1 million numbers:
N = 1e6
x = rnorm(N)
microbenchmark::microbenchmark(
Rfast = Rfast::nth(x,5,descending = T),
maxN = maxN(x,5),
order = x[order(x, decreasing = T)[5]])
Unit: milliseconds
expr min lq mean median uq max neval
Rfast 89.7722 93.63674 114.9893 104.6325 120.5767 204.8839 100
maxN 150.2822 207.03922 235.3037 241.7604 259.7476 336.7051 100
order 930.8924 968.54785 1005.5487 991.7995 1031.0290 1164.9129 100
Minimum and maximum sequential values of a vector
You can do:
range(v[which.min(v):length(v)])
[1] 1 7
Test for equality among all elements of a single numeric vector
I use this method, which compares the min and the max, after dividing by the mean:
# Determine if range of vector is FP 0.
zero_range <- function(x, tol = .Machine$double.eps ^ 0.5) {
if (length(x) == 1) return(TRUE)
x <- range(x) / mean(x)
isTRUE(all.equal(x[1], x[2], tolerance = tol))
}
If you were using this more seriously, you'd probably want to remove missing values before computing the range and mean.
R set column to maximum of current entry and specified value in an elegant way
max
gives you maximum of the whole column but for your case you need pmax
(p
arallel max
imum) so it gives you maximum of 1 or each number in the vector.
data$foo <- pmax(data$foo, 1)
data
# foo
#1 1
#2 2
#3 1
#4 2
#5 1
#6 2
#7 1
#8 2
#9 1
#10 2
Is there a vectorized parallel max() and min()?
Sounds like you're looking for pmax
and pmin
("parallel" max/min):
Extremes package:base R Documentation
Maxima and Minima
Description:
Returns the (parallel) maxima and minima of the input values.
Usage:
max(..., na.rm = FALSE)
min(..., na.rm = FALSE)
pmax(..., na.rm = FALSE)
pmin(..., na.rm = FALSE)
pmax.int(..., na.rm = FALSE)
pmin.int(..., na.rm = FALSE)
Arguments:
...: numeric or character arguments (see Note).
na.rm: a logical indicating whether missing values should be
removed.
Details:
‘pmax’ and ‘pmin’ take one or more vectors (or matrices) as
arguments and return a single vector giving the ‘parallel’ maxima
(or minima) of the vectors. The first element of the result is
the maximum (minimum) of the first elements of all the arguments,
the second element of the result is the maximum (minimum) of the
second elements of all the arguments and so on. Shorter inputs
are recycled if necessary. ‘attributes’ (such as ‘names’ or
‘dim’) are transferred from the first argument (if applicable).
Creating a function that calculates the min and max without using min() | max()
Consider head()
or tail()
after sorting:
minmax <- function(x) {
sorted_vec <- sort(x)
c(min=head(sorted_vec, 1), max=tail(sorted_vec, 1))
}
Alternatively, by indexing after sorting:
minmax <- function(x) {
sorted_vec <- sort(x)
c(min=sorted_vec[1], max=sorted_vec[length(x)])
}
Finding maximum from variables in r
You can use Map
. Map applies a function to the corresponding elements of given vectors.
probsA <- c(2.634872e-02, 6.709075e-03, 1.107573e-04, 1.708307e-03, 2.820171e-05)
probsB <- c(0.0013311712, 0.0012295459, 0.0009688963, 0.0011356790, 0.0008949280)
Map(max, probsA, probsB)
[[1]]
[1] 0.02634872
[[2]]
[1] 0.006709075
[[3]]
[1] 0.0009688963
[[4]]
[1] 0.001708307
[[5]]
[1] 0.000894928
Excluding both the minimum and maximum value
Update
Remembered after looking at @Rich Pauloo's answer, we can directly use which.max
and which.min
to get index of minimum and maximum value
as.data.frame(t(apply(df, 1, function(x) x[-c(which.max(x), which.min(x))])))
# V1 V2 V3
#1 13 11 6
#2 15 8 18
#3 5 10 21
#4 14 12 17
#5 19 9 20
Here which.max
/which.min
will ensure that you get the index of first minimum and maximum respectively for each row.
Some other variations could be
as.data.frame(t(apply(df, 1, function(x)
x[-c(which.max(x == min(x)), which.max(x == max(x)))])))
If you want to use which
we can do
as.data.frame(t(apply(df, 1, function(x)
x[-c(which(x == min(x)[1]), which(x == max(x)[1]))])))
data
set.seed(1234)
df <- as.data.frame(matrix(sample(25), 5, 5))
df
# V1 V2 V3 V4 V5
#1 3 13 11 16 6
#2 15 1 8 25 18
#3 24 5 4 10 21
#4 14 12 17 2 22
#5 19 9 20 7 23
Related Topics
Using Italic() with a Variable in Ggplot2 Title Expression
How Is Ggplot2 Plus Operator Defined
How to Know a Dimension of Matrix or Vector in R
Conditionally Remove Leading or Trailing '.' Character in R
R: Need Finite 'Ylim' Values in Function
Cant Create File Name with Time Stamp
Drawing Minor Ticks (Not Grid Ticks) in Ggplot2 in a Date Format Axis
Levenshtein Type Algorithm with Numeric Vectors
Is There Something Like a Pmax Index
R: in Barplot Midpoints Are Not Centered W.R.T. Bars
Using Tidy Eval for Multiple Dplyr Filter Conditions
Change Values in Row Based on a Column Value R
Shiny Leaflet Easyprint Plugin
Error When Mapping in Ggmap with API Key (403 Forbidden)