I have a 3d array of records from a model (looking at the spread of disease resistance), the first two dimensions are for some parameter values, the third is for time so X[1,1,:] would be how the prevalence of disease resistance changes over time. I’d like a concise way to find the first time that the prevalence passes some critical value (note: it might not reach that value).
I currently have t50 = mapslices(t -> findfirst(x -> x > 0.5, t), X, dims=3)
which does findfirst for the index of the first time the prevalence passes 0.5.
However, sometimes the prevalence doesn’t reach 0.5, and so I get an error: ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type Nothing
which I think is because findfirst is returning nothing. It doesn’t return an array of type Union{Float64, Nothing}, which would be what I’d expect.
What I’d ideally like it to do is to specify a default value (e.g. the time of the final index), and just substitute in that, but I’m not sure how to handle the nothings. Right now I’m doing it manually with 3 nested messy for loops, but a more elegant solution would be nice, if anyone has any ideas?
t50 = map(t -> findfirst(x -> x>0.5, t),
(view(X, i,j,:) for i in 1:size(X,1), j in 1:size(X,2))) .|>
t -> times[something(t), end]
which seems pretty readable, and half the length of my loopy based code. eachslice would be preferable, but it doesn’t yet support eachslice(X, dims=(1,2)), maybe that will be a later version!
I think @Tamas_Papp’s solution might work best (be most efficient, and shortest) for your immediate problem where you know what the nothing will be turned into.