How to export Julia data to a .CSV

I created an empty DataFrame and would like to export the data I got with the model solution I compiled for the DataFrame.

I am doing so, and still showing error.

df = CSV.read("//arquivo.csv")

for i ∈ 1:3
    df = JuMP.value.(N[1])
end

This is the error message that is appearing
-> Filling the remaining columns with `missing ’

This code reads a CSV file into df (which is where you get the error mesage — it may not be a valid CSV file), and then overwrites this value with JuMP.value.(N[1]).

If you want to export data to CSV, you probably need CSV.write.

I tested CSV.write and the error is gone, but I haven’t exported the data to CSV yet

I am not very familiar with JuMP, but I am under the impression that JuMP.value would return a number.

In what format would you prefer to export it into a CSV file?

Also, if you provided an MWE that produces N, it would be easier to help.

1 Like

Yes, JuMP.value returns the value that was found by the solver.
I know it’s not in MWE format, but maybe with the full code it gets better.
I would like the N build response to be exported to the CSV I created.

using JuMP, Cbc, DataFrames, CSV
model = Model(with_optimizer(Cbc.Optimizer))
P = [12;60]
M = [0.25 0.1 0.1; 0.5 0.75 0.4]
D = [36; 22; 15]

@variable(model,N[1:2], lower_bound=0)
@objective(model, Max, sum(N[i]*P[i] for i ∈ 1:2))

Pp= transpose(P)

for i ∈ 1:3
    @constraint(model, Pp*M[2*i-2+1:2*i]<= D[i])
end
print(model)

optimize!(model) #model status 
println("Objective value:  ", JuMP.objective_value(model))
println("N = ", JuMP.value.(N))

Result= CSV.write("\\File.csv")

for i ∈ 1:2
    Result = JuMP.value.(N[1])
end 

In general, you can’t appned columns to a CSV, only rows. If you are tryign to write rows to a CSV you can do

CSV.write("filename.csv", df, append=true)

I believe that for this to work df needs to be a dataframe (or other table) with the same format as what already exists in the CSV. You could for example do DataFrame(value.(N)') but this would give you the default column names :x1, :x2.

I of course don’t know the context of what you’re doing, but I suggest considering a more appropriate format for numerical data such as HDF5.jl.

Thanks for posting a self-contained problem. When I run this, it ends up with no (0) solutions, so I am not sure what you would want to print here.

(Sorry, I don’t use JuMP, so I may be missing something obvious here).

1 Like

I followed your suggestion, and did not reach my goal.
With this representation maybe I can better explain what I need. First I created an empty DataFrame, just with the field called QtdProduction then I made a for so that the DataFrame was only filled in the QtdProduction field with the compilation results of my model, but it’s giving error.

Results = CSV.read ("file.csv")

for i ∈ 1: 3
     Results [1,: QtdAProduction] = JuMP.value. (N [i])
end

CSV.write ("file.csv", Results, append = true)

Please post the error when you post example code. it makes it easier to help you.

It seems like you aren’t using your loop variable i in your loop. Additionally, : QtdAProduction is not valid Julia code. You need :QtdAProduction instead.

Results = CSV.read ("file.csv")

for i ∈ 1: 3
     Results [i,:QtdAProduction] = JuMP.value. (N[i])
end

CSV.write ("file.csv", Results, append = true)
1 Like

: QtdAProduction is the name of the field in CSV that I need to fill in.
This is the error that appears in the for.

ArgumentError: CSV.Column is read-only; to get a mutable vector from copy (col) or to make all columns mutable from CSV.read (file; copycols = true) or CSV.File (file) |> DataFrame

You should make the change suggested by the error message. For speed, CSV.jl chooses not to make mutable copies of the vectors in a DataFrame.

Once you make that change, also remember to fix the spaces in your Symbol commands. The way you are using spaces in your code is not valid Julia syntax and will cause your code to break.

I made the adjustments and the code was like this:

println("N = ",JuMP.value.(N))
Results = CSV.read("file.csv";copycols=true)#I would like .CSV were filled with the answer that println()

for i ∈ 1:3
    copy(Results)[i,:QtdAProduzir] = JuMP.value.(N[i])
end

CSV.write("file.csv",Results,append = true)

But it is not yet possible to populate .CSV with Julia’s compile result

When you write copy(Results) in your loop, you are making a new dataframe that is not Results.

Now that you have written copycols = true you do not need to copy again. Simply modify Results in the loop.

Remember that copy creates something totally new. You want to work with the existing data frame Results.

The code is adding to the .CSV the fields that were already filled, that is, duplicating the information, when it should include the empty fields of the results obtained with println().

println("N = ",JuMP.value.(N))
Results = CSV.read("file.csv";copycols=true)

for i ∈ 1:3
    copy(JuMP.value.(N[i]))
end

CSV.write("file.csv",Results,append=true)

It’s not clear what your code is trying to do. copy(JuMP.value.(N[i])) doesn’t assign assign anything to a variable.

Perhaps you mean

Results[i,:QtdAProduzir] = JuMP.value.(N[i])
2 Likes