4

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:

5
  • Is there a question you're looking to get answered here? Or do you intend for the findInterval definition to be the answer? If so, it'd be clearer if you removed that from the question section and instead post it as an answer to your own question. This is ok! And even encouraged! meta.stackoverflow.com/questions/250204/… Commented May 21, 2016 at 22:31
  • Hi Matt, I was looking for how to do something like that findInterval function with a base Julia function. Based on the link above there should exist a way to do this without having to write a custom function. Commented May 21, 2016 at 22:44
  • 4
    If your input vector is always sorted then searchsortedlast will do what you want, although you might want to wrap it in your own function that checks for a return of 0 or length(vec) and performs whatever behaviour you want when the input x is smaller than (or greater than) every element in vec. Commented May 21, 2016 at 23:33
  • Hi thanks @ColinTBowers. That works great. searchsortedlast( [1.1, 2.1, 3.1, 4.1], 2.6) does the job. Commented May 22, 2016 at 17:47
  • 1
    No probs. I'll turn it into an answer. Commented May 23, 2016 at 0:02

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.