In R, I have a matrix M
of the form
lower upper value
0.1 0.2 1.2
0.2 0.3 2.4
0.3 0.4 -0.3
And a vector v
with values in (0,1). For each value in v
, I want to find the corresponding row in M
such that the value is between the 'lower' and 'upper' values in that row, and get the corresponding number from the value
column. The output should be a vector y
of the same length as v
where each element of y
is the relevant 'value' as described above. How should I do this? I know I need to use the apply
function but can't think of the most efficient way.
For example: For the M
above, suppose v = c(0.12, 0.34)
. Then the expected output is y = c(1.2, -0.3)
CodePudding user response:
Use cut
with each of the v
values to find which range it falls into:
# example data for `v`:
set.seed(1)
v <- round(runif(5, min=0.1, max=0.4),2)
#[1] 0.18 0.21 0.27 0.37 0.16
M[, "value"][cut(v, c(M[1, "lower"], M[, "upper"]))]
#[1] 1.2 2.4 2.4 -0.3 1.2
Where M
was:
M <- as.matrix(read.table(text="lower upper value
0.1 0.2 1.2
0.2 0.3 2.4
0.3 0.4 -0.3", header=TRUE))
CodePudding user response:
M[findInterval(v, c(M[1,'lower'], M[,'upper'])), 'value']
[1] 1.2 -0.3
CodePudding user response:
Another option is to use sapply
to pull value
that fits the condition from v
.
sapply(v, \(x) M[x > M[, "lower"] & x < M[, "upper"],][["value"]])
#[1] 1.2 -0.3
Data
M <- structure(c(0.1, 0.2, 0.3, 0.2, 0.3, 0.4, 1.2, 2.4, -0.3), .Dim = c(3L,
3L), .Dimnames = list(NULL, c("lower", "upper", "value")))
v = c(0.12, 0.34)