Como converter uma matriz de tipo misto para DataFrame em Julia reconhecendo os tipos de coluna
Um recurso interessante dos DataFrames é que ele pode armazenar colunas com tipos diferentes e "reconhecê-las" automaticamente, por exemplo:
using DataFrames, DataStructures
df1 = wsv"""
parName region forType value
vol AL broadL_highF 3.3055628012
vol AL con_highF 2.1360975151
vol AQ broadL_highF 5.81984502
vol AQ con_highF 8.1462998309
"""
typeof(df1[:parName])
DataArrays.DataArray{String,1}
typeof(df1[:value])
DataArrays.DataArray{Float64,1}
No entanto, quando tento alcançar o mesmo resultado a partir de uma matriz (importada da planilha), "perco" essa conversão automática:
dataMatrix = [
"parName" "region" "forType" "value";
"vol" "AL" "broadL_highF" 3.3055628012;
"vol" "AL" "con_highF" 2.1360975151;
"vol" "AQ" "broadL_highF" 5.81984502;
"vol" "AQ" "con_highF" 8.1462998309;
]
h = [Symbol(c) for c in dataMatrix[1,:]]
vals = dataMatrix[2:end, :]
df2 = convert(DataFrame,OrderedDict(zip(h,[vals[:,i] for i in 1:size(vals,2)])))
typeof(df2[:parName])
DataArrays.DataArray{Any,1}
typeof(df2[:value])
DataArrays.DataArray{Any,1}
Existem várias perguntas sobre S.O. sobre como converter uma matriz em dataframe (por exemplo,DataFrame da matriz com cabeçalho, Converter matriz Julia em dataframe), mas nenhuma das respostas aqui lida com a conversão de uma matriz de tipo misto.
Como criar um DataFrame a partir de uma matriz que reconhece automaticamente o tipo das colunas?
EDIT: Ifez benchmark das três soluções: (1) converta o df (usando o construtor de dicionário ou matriz. O primeiro é mais rápido) e aplique try-catch para conversão de tipo (minha resposta original); (2) converta em string e use df.inlinetable (resposta de Dan Getz); (3) verifique o tipo de cada elemento e sua consistência em colunas (resposta de Alexander Morley).
Estes são os resultados:
# second time for compilation.. further times ~ results
@time toDf1(m) # 0.000946 seconds (336 allocations: 19.811 KiB)
@time toDf2(m) # 0.000194 seconds (306 allocations: 17.406 KiB)
@time toDf3(m) # 0.001820 seconds (445 allocations: 35.297 KiB)
Então, louco, a solução mais eficiente parece "derramar a água" e reduzir o problema para um já resolvido ;-)
Obrigado por todas as respostas.