هنروقتان
هنروقتان

Reputation: 788

How to fill `missings` in a vector using next valid observation

Is there any specific function for filling missings in an array? MWE:

x = [missing,missing,2,3,missing,4]
desired = [2,2,2,3,4,4]

Upvotes: 3

Views: 140

Answers (3)

هنروقتان
هنروقتان

Reputation: 788

I come up with this solution, however, I wish accumulate! has reverse option:

function bf!(x)
   init = x[end]
   @inbounds for i in reverse(eachindex(x))
       ismissing(x[i]) ? x[i] = init : init = x[i]
   end
   x
end

Upvotes: 0

longemen3000
longemen3000

Reputation: 1313

that functionality isn't in the Base language, but it is in Impute.jl. What you are looking is known as Next Observation carried Backward Imputation (nocb). you can do that with that julia package in the following way:

using Impute (if you don't have the package in your enviroment, add it)
x = [missing,missing,2,3,missing,4]
y = copy(x)
Impute.nocb!(x) #implace, overwrites x
z = Impute.nocb(y) #creates a new vector 

it also has other forms of data imputation, so if you are going to impute tabular data, that's the most secure way.

you could also implement your own nocb. this is the implementation used by Impute.jl, with some simplifications:

#implace version
function nocb!(data::AbstractVector{Union{T, Missing}}) where T
    @assert !all(ismissing, data)
    end_idx = findlast(!ismissing, data)
    count = 1
    for i in end_idx - 1:-1:firstindex(data)
        if ismissing(data[i])
            data[i] = data[i+1]
        else
            end_idx = i
            count = 1
        end
    end
    return data
end
#out of place version
nocb(x) = nocb!(copy(x))

Upvotes: 4

bichanna
bichanna

Reputation: 1044

I do not know one, but you can always create one:

for i in 1:length(array)
    if array[i] === missing
        array[i] = 1 # whatever you choose
    end 
end

Note: when you println out the type of new array, you see Vector{Union{Missing, Int64}}

Upvotes: 0

Related Questions