Reputation: 1492
The Question: I was hoping to find a function like findInterval in R which gives inputs a scalar and a vector representing interval starting points and returns the index of what interval the scalar falls in. For instance in R:
findInterval(x = 2.6, vec = c(1.1,2.1,3.1,4.1))
#[1] 2
In this exchange someone gave a function that does this functionality in Julia (See next section). Apparently the base indexin
function does this task though. I was wondering how to get indexin
function (or another base function) to do this. I know Julia loops are fast and I could write a function but I would rather not do that if there is an inbuilt function and this should be a common problem.
When I try the indexin
function with the same numbers I used in R above I get:
indexin([2.6], [1.1 2.1 3.1 4.1])
# 1-element Array{Int64,1}:
# 0
Which just indicates that 2.6 is not in the vector as it (as I understand) is looking to match values rather than placing a scaler in an interval.
Function from above referenced link (with my changes to input\output datatypes)
function findInterval(x::Float64,vec::Array{Float64})
out = zeros(Int,length(x))
vec = unique(vec)
sort!(vec)
for j in 1:length(x)
if x[j] < vec[1]
out[1] = 0
elseif x[j] > vec[end]
out[end] = 0
else
out[j] = searchsortedfirst(vec,x[j])-1
end
end
return out
end
Which works as intended:
findInterval(2.6, [1.1 2.1 3.1 4.1])
# 1-element Array{Int64,1}:
# 2
Related Questions from SO: Other questions on SO look for finding the index of exact matches between an input value and a vector:
Upvotes: 4
Views: 960
Reputation: 18560
If your input vector is always sorted, then searchsortedlast
will do what you want, e.g.
vec = [1.1, 2.1, 3.1, 4.1]
x = 2.6
searchsortedlast(vec, x)
However, note that searchsortedlast
will return 0
if x < vec[1]
, and will return length(vec)
if x > vec[end]
. So you might want to write your own custom behaviour that checks for these outcomes, e.g. if you want to always return 0
if x
is not in any of the intervals in vec
, you could write:
function find_interval(vec, x)
i = searchsortedlast(vec, x)
i == length(vec) && (i = 0)
return(i)
end
Also, if you work a lot with sorted vectors, you might be interested in a package I've written for sorted vectors in Julia, but have never gotten around to adding to METADATA
. The source of SortedVectors
package is here.
Upvotes: 4