我正在移植 R 中的自定义功能。我想使用Julia Dataframes存储我的数据。我喜欢用列名而不是数组索引来引用,因此我正在使用Dataframes包。 我简化了以下说明:
if( DataFrame(x=1).x .>1) end
错误是:
错误:TypeError:在布尔上下文中使用的非布尔(BitArray {1})
有没有简单的解决方法可以让我继续使用DataFrames?
答案 0 :(得分:3)
表达式:
DataFrame(x=1).x .> 1
执行以下操作:
DataFrame
x
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
,则更容易记住nrow
和ncol
函数。
现在,关于您的问题,您可以写:
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