Search code examples
matlabcsvvariablesworkspace

Take string from cell array for name of variable in matlab workspace


I have a large amount of .csv files from my experiments (200+) and previously I have been reading them in seperately and also for later steps in my data handling this is tedious work.

co_15 = csvread('CO_15K.csv',5,0);
co_25 = csvread('CO_25K.csv',5,0);
co2_15 = csvread('CO2_15K.csv',5,0);
co2_80 = csvread('CO2_80K.csv',5,0);
h2o_15 = csvread('H2O_15K.csv',1,0);
etc.....

So I want to make a cell at the beginning of my code looking like this and then a for loop that just reads them automatically.

input = {'co_15' 5;'co_25' 5;...
         'co2_15' 5; 'co2_80' 5;...
         'h2o_15' 1; 'h2o_140' 1;...
         'methanol_15' 5;'methanol_120' 5;'methanol_140' 5;...
         'ethanol_15' 5;'ethanol_80' 1;'ethanol_140' 5;...
         'co2_ethanol_15' 5 ;'co2_ethanol_80' 5;...
         'h2o_ethanol_15' 1 ;'h2o_ethanol_140' 1;...
         'methanol_ethanol_15' 5;'methanol_ethanol_120' 5;'methanol_ethanol_140' 5};

for n = 1:size(input,1)
    input{n,1} = csvread(strcat(input{n,1},'k.csv'),input{n,2},0);
end

The cell in this code is 19 rows and 2 columns, the rows are all the files and the columns will contain the parameters to handle the data. Now the problem I can't find a solution for is that my first column is a string name and I want that string name to be the name of the variable where csvread writes its data to but the way I set it up now it just overwrites the string in the first column of the cell with the csv data. To be extra clear I want my matlab workspace to have variables with string names in the first column containing the data of my csv files. How do I solve this?


Solution

  • You don't actually want to do this. Even the Mathworks will tell you not to do this. If you are trying to use variable names to keep track of related data like this, there is always a better data structure to hold your data.

    One way would be to have a cell array

    data = cell(size(input(:,1)));
    for n = 1:size(input,1)
        data{n} = csvread(strcat(input{n,1},'k.csv'),input{n,2},0);
    end
    

    Another good option is to use a struct. You could have a single struct with dynamic field names that correspond to your data.

    data = struct();
    for n = 1:size(input,1)
        data.(input{n,1}) = csvread(strcat(input{n,1},'k.csv'),input{n,2},0);
    end
    

    Or actually create an array of structs and hold both the name and the data within the struct.

    for n = 1:size(input, 1)
        data(n).name = input{n,1};
        data(n).data =  csvread(strcat(input{n,1},'k.csv'),input{n,2},0);
    end
    

    If you absolutly insist on doing this (again, it's is very much not recommended), then you could do it using eval:

    for n = 1:size(input, 1)
        data = csvread(strcat(input{n,1},'k.csv'),input{n,2},0);
        eval([input{n, 1}, '= data;']);
    end