在 Julia 中转换 DataFrame 时如何跳过缺失值

Roy*_*lue 4 missing-data dataframe julia

我想转换 Julia DataFrames.DataFrame 中一列中的每个元素,但这样做时跳过缺失值(让它们完整地保留在表中)。

作为一个简单的例子,我们可以这样做:

using DataFrames, DataFramesMeta

@linq DataFrame(mode=[1,2,missing]) |>
transform(
    mode = map(x->(if x === missing missing elseif x in ([0:5...]) x+1 else missing end), :mode)
)
Run Code Online (Sandbox Code Playgroud)

但它看起来或多或少杂乱无章。会有更优雅或更简洁的方式吗?

我阅读了 Query.jl 和 DataFramesMeta.jl 文档,希望找到一种方法,通过该方法,我不必显式地编写跳过缺失值的代码。

编辑: 我认为以下是我能想到的最好的:

using DataFrames, DataFramesMeta, DataValues

skipmap(f, c) = map(x->(if x===missing missing else f(x) end), c)

@linq DataFrame(mode=[1,2,missing]) |>
transform(
    mode = skipmap(x->if x in ([0:5...]) x+1 else x end, :mode)
)
Run Code Online (Sandbox Code Playgroud)

我认为如果 map() 以接受第三个参数 y(因此是 map(f,c,y))的方式进行扩展,并且如果这些元素属于 y,则它们在数组中保持完整,那将会很棒。

Bog*_*ski 5

passmissing由 DataFrames.jl 导出的内容可以满足您的需求。例如,您可以使用这样的单行:

julia> passmissing(x -> x + (x in 0:5)).([1,2,missing,4,5,6])
6-element Array{Union{Missing, Int64},1}:
 2
 3
  missing
 5
 6
 6
Run Code Online (Sandbox Code Playgroud)

另外,如果您传递它们,您可以使用广播作为+in函数隐式返回,例如:missingmissing

julia> x = [1,2,missing,4,5,6]
6-element Array{Union{Missing, Int64},1}:
 1
 2
  missing
 4
 5
 6

julia> x .+ in.(x, Ref(0:5))
6-element Array{Union{Missing, Int64},1}:
 2
 3
  missing
 5
 6
 6
Run Code Online (Sandbox Code Playgroud)

或者

julia> (v -> v + in(v, 0:5)).(x)
6-element Array{Union{Missing, Int64},1}:
 2
 3
  missing
 5
 6
 6
Run Code Online (Sandbox Code Playgroud)