1

For my program input is a csv file with some variable names and their values.

| var name       | value          |
| --------       | -------------- |
| a.b            | 345            |
| a.c._0_.field1 | 322            |
| a.c._0_.field2 | 5              |
| a.c._1_.field1 | 32             |
| a.c._1_.field2 | 50             |

In my code, I want to read this file and create struct variables with value mentioned in the file with following constraints.

  1. None of the variables' names are known. It should be thus create them dynamically
  2. All the sub structs are separated by .
  3. And in case of array, different indexes are mentioned with _%d%_.

In above case, struct a will have data:

a.b = 345
a.c(1).field1 = 322
a.c(1).field2 = 5
a.c(2).field1 = 32
a.c(2).field2 = 50

How can I create struct named a and save to mat file? I could do it using eval however, since it is not recommended, I was wondering if same could be achieved using setfield getfield

7
  • 1
    AFAIK you can't create a without using eval. Otherwise, all fields can be set as usual; simply read in your file, grab the string in the first column, strplit('.'), then use each string as a field name: my_struct.splitted_string(1) etc. Given you changed the CSV after your previous question, I suspect this is an XY problem. There might well be a better way to get your data into MATLAB than creating this CSV file. Commented May 24, 2022 at 7:28
  • 2
    You need to parse the string, and convert it to indexing operations. This is not hard. The hard part is creating a variable with a name specified in the CSV file. It can be done with eval, but it's just a really bad idea, for many reasons. I suggest instead that you create a struct data, containing all these variables: data.a.b, .data.a.c(1).field1, etc. Commented May 24, 2022 at 7:28
  • 2
    Create the indexing operations using substruct and subsasgn. Commented May 24, 2022 at 7:31
  • 1
    Could you please edit your question to give more background on how you create your CSV in the first place and what you want to do with that data in MATLAB? It looks like you have control over how you create your CSV, which makes me think that you could structure your data transfer a lot more efficient than by trying to create variables based on text in a separate file. Commented May 24, 2022 at 7:36
  • I do not have control over creating CSV file. My only issue is I cannot understand how to do indexing. Since, I finally want to save it to mat file, I am okay with creating data struct. and when I save it like save('out.mat', '-struct', 'data') a gets stored as it is. Commented May 24, 2022 at 7:51

1 Answer 1

2

I'll assume here you've read your file already into MATLAB here; you can use strsplit() to split your variable name on the dot, check whether the entry corresponds to a number or field name, and create your struct with those. You can use a substruct(), in combination with subsref() or subsasgn(), to do your indexing:

data = struct;  % Initialise your final structure
% Insert a loop here over all your rows
parts = strsplit(my_str, '.');  % split your string
indx = struct;
for ii = 1:numel(parts)
    if parts{ii}(1) ~= '_' || parts{ii}(end) ~= '_'
        indx(ii).type = '.';
        indx(ii).subs = parts{ii};
    else
        indx(ii).type = '()';
        indx(ii).subs = {str2double(parts{ii}(2:end-1))};
    end
end
data = subsasgn(data, indx, my_data);

I do think this is an XY problem. There's probably a better way to export your data from whatever you used to create the CSV and a better way to load it into MATLAB for later use. Please do explain how you create your CSV in the first place and what you want to do with the data in MATLAB (or in your .mat file). Repackaging CSV files to .mat files just for the thrill of it will hardly be your goal. Thus, please ask about your problem (X), rather than your attempted solution (Y), in order to get more helpful responses.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.