Contains in cells extracted from a structure runs into char class problems

Hi everyone,
Gonna try to be brief. Basically I have a structure with a certain number of columns, and I need to know if a certain element already exists in the column, as to retrieve its index and then check other columns on the same row.
So if indications is the struct, and curr_ID is what I am trying to look for I coded something like this:
if secondPass && contains({indications.Patient_ID}, curr_ID)
idx = find(contains({indications.Patient_ID}, curr_ID),1, 'first');
end
(...)
Now the problem is that contains is outputing and error saying that "First argument must be text". Has anybody encountered this?
To be clear, contains works with cells, and if you do A = {indications.Patient_ID} you will see that A is a cell populated with the text from all the columns of Patient_ID. I also use contains with a different cell (ZZ for example) that originates from a function and there it works fine. I don't know if anybody has noticed but when using A={struct.field} what I actually get when looking using the variable viewer is a something that looks like this:
'ID111'
'ID112'
'ID113'
...
However, for my other cells of chars when looking using the varaible viewer I do not see the ' around the words. I wonder if this is a problem even though both class(A{1,1}) and class(ZZ{1,1}) both come out as char.
Thanks in advance for the help!

 Akzeptierte Antwort

abc = {'def', 'gaha', 'hello'}
abc = 1x3 cell array
{'def'} {'gaha'} {'hello'}
contains(abc, 'gaha')
ans = 1x3 logical array
0 1 0
so contains() works properly for cell arrays of character vectors.
This suggests that indications.Patient_ID are not character vectors. What shows up for
unique(cellfun(@class, {indications.Patient_ID}, 'uniform', 0))
?
I speculate that some of the Patient_ID might be empty [] instead of empty '' so the {} does not generate a cell array of character vectors.

1 Kommentar

Herberto
Herberto am 21 Jan. 2025
Verschoben: Walter Roberson am 21 Jan. 2025
You are absolutely right! There was one instance of [] which should not have happened but it did. This was then considered a double, and indeed unique(cellfun(@class, {indications.Patient_ID}, 'uniform', 0)) threw out char and double!
If I remove the empty eveything works fine.
Thank you very much for the help :)

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

埃博拉酱
埃博拉酱 am 21 Jan. 2025
Bearbeitet: 埃博拉酱 am 22 Jan. 2025
I suggest you upload some .mat sample data. There are many ambiguities in your description.
The weirdest behavior in your code is to encapsulate a field of the struct into a cell: I can't imagine the point of such extra move. It is recommended that you try:
contains(indications.Patient_ID, curr_ID)
20250122
Code above is based my understanding that you have a scalar struct "indications" with a column vector field "Patient_ID". If that's not the case - that you actually have a column vector of structs "indications" with each of them have a char row vector field "Patient_ID", then you have @Walter Roberson.

7 Kommentare

Herberto
Herberto am 21 Jan. 2025
Verschoben: Stephen23 am 22 Jan. 2025
I mean that simply doesn't work. You can't pass a field like that, it won't work... You could do for example [indications.Patient_ID] but then the output is all the fields concatenated, and I need to know the index at which it occurs.
"The weirdest behavior in your code is to encapsulate a field of the struct into a cell: I can't imagine the point of such extra move."
It is not weird at all. The OP correctly uses a comma-separated list to transfer the content of a non-scalar structure into a cell array (which is an array accepted by CONTAINS):
In contrast your suggested syntax will not work with a non-scalar structure, in general it will throw an error due to all of the extra inputs provided when calling the function:
indications = struct('Patient_ID',{'ID1','ID2','ID3','ID4'})
indications = 1x4 struct array with fields:
Patient_ID
curr_ID = 'ID2';
contains(indications.Patient_ID, curr_ID)
Error using contains
Incorrect number of arguments. Each parameter name must be followed by a corresponding value.
@Stephen23 Then the OP is not telling the truth. What he said is that "I have A structure with a certain number of columns". "A" here should mean a scalar.
@Herberto So do you want to withdraw your description about "A structure" ?
@埃博拉酱 no I don't. Indications is a struct, Patient_ID is one of the fields. You can't output entire columns (fields) of structures the way you were suggestion and Stephen took the time to explain you why. Anyway, somebody else already gave an answer that solved the problem. Have a nice day.
埃博拉酱
埃博拉酱 am 22 Jan. 2025
Bearbeitet: 埃博拉酱 am 22 Jan. 2025
@Herberto So can you answer me whether "indications" is a scalar or not? Syntactically you can't use "A struct" to refer to a non-scalar variable of struct type. Or do you really know what is a scalar and what is not?
If your "indications" variable is not a scalar of struct, you can't say "a struct". Instead you should say "a vector of structs". It's very misleading in MATLAB if you mix these terms up.
I would argue that from the moment I said "a structure with a certain number of columns (...) and then check other columns on the same row" it was clear it was a non-scalar structure, and everybody else understood it clearly. Given the solution it is should also be clear that it is non-scalar, as the problem I described would not occur with a scalar structure.
The issue has been fixed, so I don't see the need to continue a line of questioning that looks more personal than technical at this point.
Enjoy your day.
@Herberto I really have no idea how I can distinguish the following two possibilities:
indicationsScalar=struct;
indicationsScalar.Patient_ID={'Patient1';'Patient2';'Patient3'}
indicationsVector=struct(Patient_ID={'Patient1';'Patient2';'Patient3'})
indicationsScalar =
包含以下字段的 struct:
Patient_ID: {3×1 cell}
indicationsVector =
包含以下字段的 3×1 struct 数组:
Patient_ID
These two variables have very different type structures and both fit your description. What's more interesting is that if indications is a scalar as I understood:
>> contains({indicationsScalar.Patient_ID}, 'Patient1')
错误使用 contains
第一个参数 必须为文本。
MATLAB will just throw the same error as you encountered without the need of having an empty double array in one of your rows. That's why my first instinct is that your "indications" is a scalar.

Melden Sie sich an, um zu kommentieren.

Kategorien

Produkte

Version

R2023b

Community Treasure Hunt

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

Start Hunting!

Translated by