Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Outputting strings without quotation marks when using writetable() with DataFrames.jl in Julia?

The default for writing strings in DataFrames to a file using writetable is that they are surrounded by quotation marks:

using DataFrames
df = DataFrame(letters=["A","B","C"],numbers=[1,2,3])
writetable("df_file", df, separator='\t')

produces the following file:

"letters"   "numbers"
"A" 1
"B" 2
"C" 3

There is an option to change the quotemark character:

writetable("df_file", df, separator='\t', quotemark='.')

.letters.   .numbers.
.A. 1
.B. 2
.C. 3

but this doesn't work if no character is specified

writetable("df_file", df, separator='\t', quotemark='')
ERROR: syntax: invalid character literal

My question is: how can I write strings without any quotation mark character at all? This would be the output I would need:

letters numbers
A   1
B   2
C   3

I'm currently using Julia version 0.4.1, DataFrames package version 0.6.10.

like image 630
Ian Marshall Avatar asked Aug 03 '16 07:08

Ian Marshall


2 Answers

According to this GitHub discussion, the creators of the DataFrames package do not trust users with this kind of power to have control over their output.

My personal recommendation would be to just convert to Array and then use Julia's writedlm() which does trust users to know what they want to write to file:

writedlm(FileName, convert(Array,df), '\t')

To include a header you can use something like this:

open(FileName, "w") do f
    writedlm(f, names(df)', '\t')
    writedlm(f, convert(Array,df), '\t')
end

See also this related question with a similar answer: Is there a way to use strings as separators in writetable() - Julia

like image 114
Michael Ohlrogge Avatar answered Nov 07 '22 16:11

Michael Ohlrogge


I would be tempted to just write a quickie somewhat like this:

julia> n, p = size(df)
(3,2)

julia> open("/tmp/df_file.txt", "w") do f
            for i in 1:n
               for j in 1:p
                  write(f, string(df[i, j]))
                  write(f, "\t")
               end
               write(f, "\n")
             end
        end

or if I had more time I might start writing something like this (a modified version of the source of the writetable function):

julia> function myprinttable(io::IO,
                           df::AbstractDataFrame;
                           header::Bool = true,
                           separator::Char = ',',
                           quotemark::AbstractString = "\"",
                           nastring::AbstractString = "NA")
           n, p = size(df)
           etypes = eltypes(df)
           if header
               cnames = DataFrames._names(df)
               for j in 1:p
                   print(io, quotemark)
                   print(io, cnames[j])
                   print(io, quotemark)
                   if j < p
                       print(io, separator)
                   else
                       print(io, '\n')
                   end
               end
           end
           quotestr = quotemark
           for i in 1:n
               for j in 1:p
                   if ! (isna(df[j],i))
                       if ! (etypes[j] <: Real)
                           print(io, quotemark)
                           DataFrames.escapedprint(io, df[i, j], quotestr)
                           print(io, quotemark)
                       else
                           print(io, df[i, j])
                       end
                   else
                       print(io, nastring)
                   end
                   if j < p
                       print(io, separator)
                   else
                       print(io, '\n')
                   end
               end
           end
           return
       end
julia> open("/tmp/df_file.txt", "w") do f
          myprinttable(f, df, header=true, separator='\t', quotemark="")
       end

(Mostly untested.)

which just changes quotemark from Char to String. (I'm still getting used to Julia's use of Char instead of single-character Strings in certain places.

like image 34
daycaster Avatar answered Nov 07 '22 16:11

daycaster