How to reference variable using string with the same name?

I have around a hundred tables of data (each table is an individual test), each with 4 columns and 10000+ rows. As I want to be able to manipulate and access the data of every table, simaltanously. Each of the tests is named in a systematic way such as: t01a, t02a, t03a, t01b, t02b, t03b... . I have created another table for each of the names for each test deconstructed into separate strings like: {"t" "01" "a"; "t" "02" "a"...}. My plan was to go through each row of this name table, concatenate the row to get the string which has the same name as the table containing the data for a single test. Unfortunately I do not know how to use the string to reference the table which has the same name.
for i = 1:totalNumTests
currentTest = string(table2array(Names(i,:)));
result = "";
for c = 1:length(currentTest) % current test that I would like to manipulate
result = result + currentTest(1, c); % concatenates parts of name table to construct full name of a single test
end
for u = 1:length(result.aY) %this is where error originates because it is trying to reference a table when it is a string at the moment. aY is one column of the data in the test tables
result.aY(u) = result.aY(u) - 9.81183; % i am now trying to edit the current test data
end
end

4 Kommentare

Stephen23
Stephen23 am 23 Mai 2018
Bearbeitet: Stephen23 am 23 Mai 2018
By far the best solution is to avoid this situation entirely. Luckily this is usually trivially easy to avoid, e.g. by load-ing into an output variable instead of simply spamming variables into the workspace:
S = load(...);
Note that dynamically accessing variable names is one way that beginners force themselves into writing slow, buggy, complex code that is hard to debug. You can read more about why here:
Note that putting any kind of meta-data into variable names makes code slow, complex, and buggy. For example it is actually much easier to process multiple .mat files if they all contain exactly the same variables, not ones with different names. Then looping over them and importing the data is trivially easy. Meta-data like you describe is just a pseudo-index, and as such it would be better turned into a real index. Real indices are much simpler, much more efficient, and much easier to debug. You could easily use a cell array for your data when you import it.
Thus the most important question is: how did you get all of those variables into the workspace?
Thank you very much! This had definitely put me in the right direction. I was wondering if you could help me figure out how I should best organise my data. So I have seven different sets of tests, each set of tests has between three and six individual tests. Then each test has two different stages, and each stage was measured with two sensors, one sensor has two outputs and the other has four outputs.
I wasn't sure if I should use multidimensional structure arrays or cell arrays or something else? Additionally, since the amount of data collected varies from test to test. Also each data file starts out as a csv file.
Haha well for the first 25 I justed manually used the import tool because I was not yet aware of the csvread command.
Stephen23
Stephen23 am 25 Mai 2018
Bearbeitet: Stephen23 am 25 Mai 2018
@Malcolm Tisdale: of course I am happy to help you organize your data: well organized data makes code much simpler and easier to write, so is well worth the effort. Note that there is no "perfect" way to organize data, because how to arrange data depends on the data itself (e.g. size, class, etc), how the data will be processed (e.g. vectorized code or loops, etc), the sequence in which the data will be processed, the clarity of the required code, what methods are easy to use, etc.
For example, do you:
  • first process the three-six tests for stage one and then process the three-six tests for stage two, OR
  • process both stage one and two for test one, then both stage one and two for test two, etc.
Each of these would imply a different way to arrange your data, because depending on how you nest your data you can easily access the required parts using indexing, and this makes the code simpler and more efficient. There is no magic "key" to figuring this out: just lots of thinking and testing things out. Don't rush, and don't be afraid to try out different combinations.
For example: do all of the sensor measurements have the same number of values? Do you perform calculations that require all two/four of the sensor values together? If you need to average the two/four sensor outputs at each sample point in time, then putting all of the sample values into one matrix would make this trivial:
M = [1,2,3,...; % sensor A channel 1
3,5,7,...; % sensor A channel 2
2,4,6,...; % sensor A channel 3
...
then it is trivial to calculate a mean, differences between values, plot them, or do whatever signal processing, statistics, etc:
mean(M,1)
plot(M.')
However if what you are comparing is value from one sensor channel to the same channel during another test, then another way of arranging the data might be best... So you really have to ask yourself how you are going to be processing the data.
I would add that in general data should be kept together as much as possible, so if you import matrices then these should probably be left as matrices/tables.
Because the number of sensor channels is fixed you might like to consider non-scalar structures in a cell array, which makes it easy to store and access a different number of subtests for each test (this is basically a kind of ragged array), e.g.:
C{1}(1,1).sensorA = ...
C{1}(1,1).sensorB = ...
C{1}(1,2).sensorA = ... % first test, first subtest, second stage
...
C{1}(3,2).sensorB = ... % first test, third subtest, second stage
C{2}(1,1).sensorA = ... % second test, first subtest, first stage
...
C{7}(6,2).sensorB = ... % seventh test, sixth subtest, second stage
If you want more help then please upload some sample files and give an indication of how you are going to process the data.
Stephen, please consider adding a bit to your standard answer (or at least to the standard Answer if not to the paragraph you posted as the first comment) given the overloading (colloquially, not in terms of object inheritance) of two terms.
The term "table" could refer to the table data type or it could refer to a regular array of tabular data.
The term "variable" could mean an independent variable of some data type, or it could refer to a column in a table or timetable array (where the table or timetable array itself is a variable in the first sense.)
If you want to add a new variable (the second meaning) to a table (the first meaning) where the name of the new variable is stored as text, which could be what the original poster is doing based on some of the functions they're using, IMO this is okay (from a "poofing" standpoint) since the variable is part of the table and not an independent entity taking up namespace. In that case even though we call it a "variable" I think it can be treated more like the field in a struct array.
There are (at least) two different ways (at least three as of R2018a) you can retrieve, modify, or create a variable in a table when the name of the new variable is stored as text.
T = array2table(magic(5))
newname = 'Var6';
T.(newname) = randi([50 100], 5, 1)
newname2 = 'Var7';
T{:, newname2} = randi([200 300], 5, 1)
% addvars introduced in R2018a
newname3 = 'Var3p5';
T = addvars(T, randi([500 1000], 5, 1), ...
'NewVariableNames', newname3, 'After', 'Var3')

Melden Sie sich an, um zu kommentieren.

Antworten (0)

Kategorien

Produkte

Gefragt:

am 23 Mai 2018

Kommentiert:

am 25 Mai 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by