4

in Matlab I have several records of a database stored in the matrix DataMatrix. Each row of the matrix is a record and each column is the value of a property of the record. To make the program easy to understand for each column of DataMatrix I defined a variable name explaining what property is associated to the column, that is:

ColApple = 1;
ColOrange = 2;
ColLemon = 3;
...

I have about 50 columns to name.

My problem is that the values in DataMatrix are used in different functions and I would like to always use the columns name to work on the data in DataMatrix. So I have to share between different functions the values of ColApple, ColOrange, ColLemon, ...

Up to now I thought to two possible approaches:

  1. Making the columns name global

  2. Define a function returning the values for the columns name, that is:

    [ColApple, ColOrange, ColLemon, ... ] = getColNames

I would avoid the global solution because I think it is dangerous and also because I would like the columns name constant if possible. The second approach is better but since I have 50 columns I do not know if it is a good idea to have a function returning 50 different values (also it is difficult to maintain in my opinion).

Anyone has a more robust or maintainable approach to solve this problem? I am sure I am not the first one to deal with this but I was not able to find a solution.

2 Answers 2

7

This is perfect for container maps. A container map allows for creating a dictionary. For example

fruits = containers.Map({'Apple', 'Orange', 'Lemon'}, [1, 2, 3])

will create the dictionary

'Apple'   ->   1
'Orange'  ->   2
'Lemon'   ->   3

you can find the desired column number with

>> fruits('Orange')

ans =

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

2 Comments

And here I was thinking I had a good solution ;) Always someone with a built-in which does exactly what is requested. Good job!
@hbaderts that is exactly what I was looking for, thanks
2

Don't use global variables, as they are prone to errors. Creating 50 variable names is not very error-proof either (see: dynamic variable naming).

I'd go with a simple cell array in this case. You can either read the names from the first row in your data matrix if they are written there, or hand write them if you're doing that now anyway.

ColumnNames = {'Col1', 'Col2', 'Col3', (...) , 'Col 50'}

This will give you a 1 x 50 cell array containing your column names. The names can be found simply by entering the correct column number, i.e. column 22 would be ColumnNames{1,22}. You can now pass the variable ColumnNames to other functions as just a single variable. In order to get the corresponding column name if you do not use dynamic variable naming, but e.g. your colApple, you can use strcmp

ColIdx = find(strcmp(ColumnNames,'colApple'));

This way the strcmp checks which cell contains the string 'colApple', and the find returns the index number of the requested cell.

I pass a lot of variables in my own code, which I do in a structure array, since that's able to store all kinds of different data and have a reasonable name for each structure entry:

result.data = [m x 9 double]
result.grid.z = ~[5000 x 5500 double]
result.filename = 'filename.asc'
...

5 Comments

thanks but I am not sure I fully understand the answer. Using your example ColumnNames{1,22} returns Col 22 so, given the column number I get the column name. Given the two functions function1 and function2 and I pass to them the variable ColumnNames I am sure that , given the same column number, I get the same column name. But what I am looking for is the contrary: given the same column name I would like to have the same column number. This way the command DataMatrix(:, Col22) = something would work on the same column both in function1 and function2
Maybe you think that after passing ColumnNames I should create the variables using something like for ii = 1: length(ColumnNames) str = [ColumnNames{1,ii} ' = ' int2str(ii)]; eval(str); end
@MeSS83 I never think that using eval is a good idea, ever. See the linked post about using Dynamic Variable Names. eval breaks everything MATLAB related and is not to be used in my opinion. If you do not move columns around in your data, then if you pass your data from one function to another, column 22 will still be column 22, so I don't see the problem there.
you are perfectly right column 22 in my case is always column 22 but in my code I did not write DataMatrix(:, 22) = something but instead I have DataMatrix(:, ColLemon) = something. I did this because I thought It was more readable and because maybe in the future the value of ColLemon will change. So I would ensure that in every function of my program ColLemon has the same value. I simply do not understand how to use your solution, passing ColumnNames, to achieve this
@MeSS83 and rightly so. I didn't know about container maps, so I hacked my way there. I do urge you to read through my linked answer on Dynamic Variable Naming though, to prevent you from using eval, with all its associated pitfalls and breakdowns.

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.