Azzera filtri
Azzera filtri

Logic statement error checking an array within a cell within a table

44 visualizzazioni (ultimi 30 giorni)
Sean
Sean il 27 Giu 2024 alle 18:02
Modificato: Voss il 27 Giu 2024 alle 20:49
Hi,
I am trying to write an if condition where if a variable name (in this case 'pressure') appears in an array that is stored in a cell of the table "podList", then the condition is true:
if 1 == ismember('pressure',settingsSet.podList(currentPod,VarNames).Properties.VariableNames)
I am getting the error: "Unrecognized table row name 'SPODD8'."
The variable "currentPod" changes in a higher loop and the first check is 'SPODD8'
See attached pictures for the structure of the table podList and VarNames.
podList is currently a 19x4 but can change to more or fewer rows based on the input pods (which are research instruments)
VarNames is currently a 1x36 cell but could aslo change based on the type of pod used. For my applications it is always either a 1x36 or a 1x42.
I also am not sure if I am calling out the row of VarNames correctly here as I haven't gotten that deep, so any help suggestions there would be appreciated!
Thank you in advance.
  5 Commenti
Stephen23
Stephen23 il 27 Giu 2024 alle 19:05
@Sean: forget about screenshots. Please upload your data in a MAT file, by clicking the paperclip button.
Sean
Sean il 27 Giu 2024 alle 19:18
Uploaded a .mat file as well (from these last two comments' requests).

Accedi per commentare.

Risposte (3)

Steven Lord
Steven Lord il 27 Giu 2024 alle 18:54
Let's break this line of code down into pieces. I've commented it out so I can run code later in this answer.
% if 1 == ismember('pressure',settingsSet.podList(currentPod,VarNames).Properties.VariableNames)
First section of code
The section settingsSet.podList refers to the table in the first picture in the post. That does look like a table array. So this section seems reasonable.
Second section of code, part 1
The section settingsSet.podList(currentPod,VarNames) will return a table consisting of the rows referred to by currentPod and the variables referred to by VarNames. I believe from the fact that you said currentPod is 'SPODD8' that you wanted this to retrieve the first row in settingsSet.podList, but that's not what it does. Sure, this looks like it should be the same as the "Index by Row Names" section on this documentation page, but the first variable in the picture is not a set of row names. Compare:
load patients
% Only need a few rows for demonstration purposes
LastName = LastName(1:5);
Age = Age(1:5);
noRowNames = table(LastName, Age)
noRowNames = 5x2 table
LastName Age ____________ ___ {'Smith' } 38 {'Johnson' } 43 {'Williams'} 38 {'Jones' } 40 {'Brown' } 49
lastNameRowNames = table(Age, RowNames=LastName)
lastNameRowNames = 5x1 table
Age ___ Smith 38 Johnson 43 Williams 38 Jones 40 Brown 49
The lastNameRowNames table has row names; I can index into it using 'Johnson', for example, to obtain row 2.
lastNameRowNames('Johnson', :)
ans = table
Age ___ Johnson 43
But I can't index into noRowNames using 'Johnson' any more than I could index into it using the value 43 from the Age variable. LastName and Age are both variables in noRowNames; neither is a set of row names.
try
noRowNames('Johnson', :)
catch ME
fprintf("This call threw error:\n%s", ME.message)
end
This call threw error: Unrecognized table row name 'Johnson'.
I could use 'Johnson' with the LastName variable in noRowNames to index into it. It's a little more verbose, but it allows you to keep LastName as data in the table rather than metadata. The results look close to the results from the operation of indexing into lastNameRowNames with row name 'Johnson'.
noRowNames(matches(noRowNames.LastName, 'Johnson'), :)
ans = 1x2 table
LastName Age ___________ ___ {'Johnson'} 43
Second section of code, part 2
In your code you refer to VarNames. But you haven't showed us the contents of that variable. Sure, your table does have a variable named VarNames, but your usage of it in that indexing expression doesn't refer to that variable. You'd need to refer to it as settingsSet.podList.VarNames to refer to that variable or settingsSet.podList.VarNames{1} to refer to the first cell in that variable from the table.
Third section of code
Okay, so if you obtain a sub-table from your array you then try to access one of its Properties. settingsSet.podList(currentPod,VarNames).Properties.VariableNames. But this isn't going to somehow refer to the VarNames variable in the table, if that's what you're expecting. Based on that picture and your statement that the table settingsSet.podList is a 19-by-4 table array, the list of VariableNames of the table is {'podName', 'VarNames', 'VarTypes', 'timezone'}. But that's not what you're trying to do, it sounds like.
Suggestion
If you want to process each row in this table, looking to see if the contents of the VarNames variable in that row contains the text 'pressure', consider using rowfun. Something along these lines ought to work, though because I don't have your actual data I can't test it. [Since it's not going to run I left it commented out.]
%{
underPressure = rowfun(@(x) ismember('pressure', x), ...
settingsSet.podList, ... % Process the rows of the settingsSet.podList table
InputVariables = {'VarNames'}, ... % Only pass the VarNames variable in
GroupingVariables = {'podName'}) % Group by values from podName
%}
The InputVariables parameter will tell MATLAB to pass only the VarNames variable from the row into the anonymous function, and the GroupingVariables parameter will tell MATLAB to group the results by the unique values in the podName variable.

Walter Roberson
Walter Roberson il 27 Giu 2024 alle 19:24
Modificato: Walter Roberson il 27 Giu 2024 alle 19:24
if 1 == ismember('pressure',settingsSet.podList(currentPod,VarNames).Properties.VariableNames)
settingsSet.podList appears to be a table. If () indexing of it works then the result would be a table. You then ask for the VariableNames property of the table... which is going to be the same as VarNames (provided VarNames is indeed names and not numeric.) This seems like a bit of a waste: you could just use VarNames directly.
Comparing 1 == to ismember() is inefficient. ismember() in this form responds with either 0 (false) or 1 (true). You can just use the ismember() result directly in the test.
if ismember('pressure',VarNames)
But it looks to me as if what you want to test is
if ismember('pressure', settingsSet.podList.VarNames{currentPod})

Voss
Voss il 27 Giu 2024 alle 19:57
settingsSet.podList = load('podList.mat').T;
settingsSet.podList
ans = 19x4 table
podName VarNames VarTypes timezone __________ ___________ ___________ ________ {'SPODD8'} {1x36 cell} {1x36 cell} 0 {'SPODD2'} {1x36 cell} {1x36 cell} 0 {'SPODD3'} {1x36 cell} {1x36 cell} 0 {'SPODD4'} {1x36 cell} {1x36 cell} 0 {'SPODD5'} {1x36 cell} {1x36 cell} 0 {'SPODD6'} {1x36 cell} {1x36 cell} 0 {'SPODD7'} {1x36 cell} {1x36 cell} 0 {'SPODD1'} {1x36 cell} {1x36 cell} 0 {'SPODD9'} {1x36 cell} {1x36 cell} 0 {'SPODE0'} {1x36 cell} {1x36 cell} 0 {'SPODE1'} {1x36 cell} {1x36 cell} 0 {'SPODE2'} {1x36 cell} {1x36 cell} 0 {'SPODE3'} {1x36 cell} {1x36 cell} 0 {'SPODE4'} {1x36 cell} {1x36 cell} 0 {'SPODE5'} {1x36 cell} {1x36 cell} 0 {'SPODE6'} {1x36 cell} {1x36 cell} 0
Nrows = size(settingsSet.podList,1);
VarNamesContainsPressure = false(Nrows,1);
for row = 1:Nrows
% currentPod = settingsSet.podList.podName{row};
if ismember('pressure',settingsSet.podList.VarNames{row})
VarNamesContainsPressure(row) = true;
end
end
VarNamesContainsPressure
VarNamesContainsPressure = 19x1 logical array
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  2 Commenti
Sean
Sean il 27 Giu 2024 alle 20:36
Is there a way to iterate by "currentPod" instead of indexing number by number based on the length of the podlist?
Voss
Voss il 27 Giu 2024 alle 20:49
Modificato: Voss il 27 Giu 2024 alle 20:49
Yes. In this case the set of pods to check is specified in podsToCheck, and those are iterated over.
settingsSet.podList = load('podList.mat').T;
settingsSet.podList
ans = 19x4 table
podName VarNames VarTypes timezone __________ ___________ ___________ ________ {'SPODD8'} {1x36 cell} {1x36 cell} 0 {'SPODD2'} {1x36 cell} {1x36 cell} 0 {'SPODD3'} {1x36 cell} {1x36 cell} 0 {'SPODD4'} {1x36 cell} {1x36 cell} 0 {'SPODD5'} {1x36 cell} {1x36 cell} 0 {'SPODD6'} {1x36 cell} {1x36 cell} 0 {'SPODD7'} {1x36 cell} {1x36 cell} 0 {'SPODD1'} {1x36 cell} {1x36 cell} 0 {'SPODD9'} {1x36 cell} {1x36 cell} 0 {'SPODE0'} {1x36 cell} {1x36 cell} 0 {'SPODE1'} {1x36 cell} {1x36 cell} 0 {'SPODE2'} {1x36 cell} {1x36 cell} 0 {'SPODE3'} {1x36 cell} {1x36 cell} 0 {'SPODE4'} {1x36 cell} {1x36 cell} 0 {'SPODE5'} {1x36 cell} {1x36 cell} 0 {'SPODE6'} {1x36 cell} {1x36 cell} 0
podsToCheck = {'SPODD8','SPODE2'};
N = numel(podsToCheck);
VarNamesContainsPressure = false(N,1);
for ii = 1:N
currentPod = podsToCheck{ii};
rows = strcmp(settingsSet.podList.podName,currentPod);
if ismember('pressure',[settingsSet.podList.VarNames{rows}])
VarNamesContainsPressure(ii) = true;
end
end
VarNamesContainsPressure
VarNamesContainsPressure = 2x1 logical array
1 1
VarNamesContainsPressure is true whenever 'pressure' appears in any element of VarNames in rows where podName is currentPod. In particular, the possibility that currentPod appears multiple times or zero times in podName is handled.

Accedi per commentare.

Categorie

Scopri di più su Tables in Help Center e File Exchange

Prodotti


Release

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by