Convert String to Float

Hi,
I have a column in a dataframe which is of type =String15. I need to convert that to float.

julia> typeof(test[!,:Conc])
Vector{String15} (alias for Array{String15, 1})

When I tried to convert the Conc variable to float using the below code, I get this error. Can someone help with the error, please? Not sure what I am missing. Thanks.

test[!,:Conc] = float.(test[!,:Conc])

Error message

ERROR: MethodError: no method matching AbstractFloat(::String15)

Closest candidates are:
  (::Type{T})(::SymbolicUtils.Symbolic) where T<:Union{AbstractFloat, Integer, Complex{<:AbstractFloat}, Complex{<:Integer}}
   @ Symbolics C:\a\PumasSystemImages\PumasSystemImages\julia_depot\packages\Symbolics\UrqtQ\src\Symbolics.jl:150
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
   @ Base char.jl:50
  (::Type{T})(::Base.TwicePrecision) where T<:Number
   @ Base twiceprecision.jl:266
  ...

Stacktrace:
 [1] float(x::String15)
   @ Base .\float.jl:294
 [2] _broadcast_getindex_evalf
   @ .\broadcast.jl:683 [inlined]
 [3] _broadcast_getindex
   @ .\broadcast.jl:656 [inlined]
 [4] getindex
   @ .\broadcast.jl:610 [inlined]
 [5] copy
   @ .\broadcast.jl:912 [inlined]
 [6] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(float), Tuple{Vector{String15}}})
   @ Base.Broadcast .\broadcast.jl:873
 [7] top-level scope

Hi @MathangiCTM you should use parse or tryparse. Here is a short example.

julia> a = ["1", "3", "5"]
3-element Vector{String}:
 "1"
 "3"
 "5"

julia> float.(a)
ERROR: MethodError: no method matching AbstractFloat(::String)

Closest candidates are:
  (::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
   @ Base char.jl:50
  (::Type{T})(::Base.TwicePrecision) where T<:Number
   @ Base twiceprecision.jl:266
  (::Type{T})(::Complex) where T<:Real
   @ Base complex.jl:44
  ...

Stacktrace:
 [1] float(x::String)
   @ Base ./float.jl:294
 [2] _broadcast_getindex_evalf
   @ ./broadcast.jl:683 [inlined]
 [3] _broadcast_getindex
   @ ./broadcast.jl:656 [inlined]
 [4] getindex
   @ ./broadcast.jl:610 [inlined]
 [5] copy
   @ ./broadcast.jl:912 [inlined]
 [6] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(float), Tuple{Vector{String}}})
   @ Base.Broadcast ./broadcast.jl:873
 [7] top-level scope
   @ REPL[2]:1

julia> tryparse.(Float64, a)
3-element Vector{Float64}:
 1.0
 3.0
 5.0

When you end up with a column like that, it’s often because CSV.read wasn’t able to figure out how to interpret something in a numerical column in the CSV file. It’s often a bit simpler to adjust the call to CSV.read instead of converting the columns afterwards. An example of a CSV that causes a string column is shown below. If the missing value is coded as NA then we’d have to tell CSV.read. (Just ignore the IOBuffer since it’s just to pass a string to CSV.read instead of a file)

julia> csv_string = "a,b\n1.0,2.0\n3.0,NA"
"a,b\n1.0,2.0\n3.0,NA"

julia> print(csv_string)
a,b
1.0,2.0
3.0,NA
julia> CSV.read(IOBuffer(csv_string), DataFrame)
2Γ—2 DataFrame
 Row β”‚ a        b
     β”‚ Float64  String3
─────┼──────────────────
   1 β”‚     1.0  2.0
   2 β”‚     3.0  NA

julia> CSV.read(IOBuffer(csv_string), DataFrame, missingstring=["NA"])
2Γ—2 DataFrame
 Row β”‚ a        b
     β”‚ Float64  Float64?
─────┼────────────────────
   1 β”‚     1.0        2.0
   2 β”‚     3.0  missing

Thanks @vijay and @andreasnoack .
Yes, as you pointed out, it was because of a character in the variable column, which was otherwise numeric entries. The CSV.read with the missingstring took care of the error.
The below code in CSV.read using the typesargument also worked.

test=CSV.read("../data/original/Individual Concen Data.csv", DataFrame, header=1,skipto = 3,types=Dict(:Concentration => Float64))
1 Like