带有数据框的条件语句[Julia v1.0]

时间:2018-08-31 20:56:24

标签: julia

我正在移植 R 中的自定义功能。我想使用Julia Dataframes存储我的数据。我喜欢用列名而不是数组索引来引用,因此我正在使用Dataframes包。 我简化了以下说明:

if( DataFrame(x=1).x .>1) end

错误是:

  

错误:TypeError:在布尔上下文中使用的非布尔(BitArray {1})

有没有简单的解决方法可以让我继续使用DataFrames?

1 个答案:

答案 0 :(得分:3)

表达式:

DataFrame(x=1).x .> 1

执行以下操作:

  1. 创建一个DataFrame
  2. 从中提取列x
  3. 使用矢量化操作1(用Julia的话广播),将该列的所有元素与.>进行比较

实际上,您得到以下一个元素数组:

julia> DataFrame(x=1).x .> 1
1-element BitArray{1}:
 false

与R相反,Julia区分矢量和标量,因此它与简单地写false不同。此外,if语句期望标量而不是向量,因此类似这样的工作:

if 2 > 1
    println("2 is greater than 1")
end

但不是这样:

if DataFrame(x=2).x .> 1
    println("success!")
end

但是,例如,这可以工作:

if (DataFrame(x=2).x .> 1)[1]
    println("success!")
end

当您从数组中提取第一个(也是在这种情况下)元素时。

请注意,在R中,如果您将多个元素向量传递给条件表达式,则会收到如下警告:

> if (c(T,F)) {
+ print("aaa") } else {print("bbb")}
[1] "aaa"
Warning message:
In
  the condition has length > 1 and only the first element will be used

在这种情况下,Julia在检查类型方面比R严格。在R中,标量和向量之间没有区别,但是在Julia中,则有。

编辑:

length(df)返回DataFrame列的数量(不是行数)。如果您来自R,则更容易记住nrowncol函数。

现在,关于您的问题,您可以写:

for i in 1:nrow(df)
    if df.x[i] > 3
        df.y[i] = df.x[i] + 1
    end
end

bigx = df.x .> 3
df.y[bigx] = df.x[bigx] .+ 1

df.y .= ifelse.(df.x .> 3, df.x .+ 1, df.y)

或使用DataFramesMeta来简化表示法:

using DataFramesMeta

@with df begin
    df.y .= ifelse.(:x .> 3, :x .+ 1, :y)
end

using DataFramesMeta

@byrow! df begin
    if :x > 3
        :y = :x + 1
    end
end