I am having a horzcat error while I try to create a structure from smaller structures.

I am having a structure with the name data (1x1) another structure (1x16) that has data inside. and finally a table (1x254) with times values.
I confused If I have bad instruction of how those 3 should be forming a structure to laser use them in EEGLAB with BIOSIG plugin (import the final structure using the pop_biosig command).
my guides to create the structures (1x16) this command
chanlocs = struct('labels', {data.Fp1,data.Fp2, data.F7, data.F3, data.F4, data.F8, data.T3, data.C3, data.C4,data.T4, data.T5, data.P3, data.P4, data.T6, data.O1, data.O2}, ...
'type', {'EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG'}, ...
'ref', {char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty}, ...
'theta', {-18, 18,-54,-39,39,54,-90,-90,90,90,-126,-141,141,126,-162,162}, ...
'radius', {0.511,0.511,0.511,0.333,0.333,0.511,0.511,0.256,0.256,0.511,0.511,0.333,0.333,0.511,0.511,0.511}, ...
'X', {0.95,0.95,0.587,0.673,0.673,0.587,6.12e-17,4.4e-17,4.4e-17,6.12e-17,-0.587,-0.673,-0.673,-0.587,-0.95,-0.95}, ...
'Y', {0.309,-0.309,0.809,0.545,-0.545,-0.809,0,0.719,-0.719,0,0.809,0.545,-0.545,-0.809,0.309,-0.309}, ...
'Z', {-0.0349,-0.0349,-0.0349,0.5,0.5,-0.0349,0.999,0.695,0.695,-0.999,-0.0349,0.5,0.5,-0.0349,-0.0349,-0.0349}, ...
'sph_theta', {18,-18,54,39,-39,-54,-0.0349,90,-90,-0.0349,126,141,-141,-126,162,-162}, ...
'sph_phi', {-2,-2,-2,30,30,-2,90,44,44,-90,-2,30,30,-2,-2,-2}, ...
'sph_radius', {0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0}, ...
'urchan',{char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty}, ...
'value',{char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty});
then use
[data t chanlocs]
to create this structure to use on EGGLAB.
however I receive the horzcat error which I can seemed to find a way to over come it.
Any ideas to resolve or have further questions to the problem please let me know.
Kostas

7 Comments

Well you simply cannot catenate disparate things in an array (or similar things of different sizes, either), so the last statement above is a nonstarter; just can't be done.
EEGLAB doesn't appear to be a TMW product; you'll need to pursue it's support channels/documentation to see how to construct an appropriate dataset; unless somebody who also happens to use it comes along by chance.
NOTA BENE: You can use construct like
N=16; % data size as variable, don't bury magic constants in code..
chanlocs=struct(... ,
type', {repmat('EEG',1,N}, ...
'ref', {repmat('',1,N}, ...
...
to make your code far easier to maintain/read instead of the explicit repeat of the same value; and, of course, you can also string together multiple repmat() calls if are subsequences of repeated values, not all one.
In order to horzcat two struct together using [], the two struct must have the same number of rows and the same fields in the same order.
S1 = struct('woo', num2cell(randi(9,5,1)))
S1 = 5×1 struct array with fields:
woo
S2 = struct('woo', num2cell(randi(9,5,1)))
S2 = 5×1 struct array with fields:
woo
[S1, S2]
ans = 5×2 struct array with fields:
woo
You cannot use [] to concatenate a struct and a numeric array, or a struct and a table.
You cannot use [] to concatenate a table and a struct or a table and a numeric array.
You can use [] to concatenate a table and a cell array:
T1 = struct2table(S1)
T1 = 5×1 table
woo ___ 6 6 1 8 7
C2 = struct2cell(S2)
C2 = 1×5 cell array
{[5]} {[8]} {[8]} {[3]} {[1]}
[T1, C2.']
ans = 5×2 table
woo Var2 ___ ____ 6 5 6 8 1 8 8 3 7 1
thank you all for your reply.
I follow up with some clarifications. EGG LAb is outside of TMW products, I am not so interest in that part.
my first question will be if a table (i.e. dimension 1x105) can be combined with chanloncs - structure of data&info (size 1x16) while first columm isside is the data in (105x1).
So, at first sight for me it is not possible thus I got the instructions to do a combine the the table (105x1) with a structure data (1x1) inside is 16 table and the 'chanlocs structure' (1x16) (inside are 16 tables (105x1) and the above labels ).
thus my first question is can you combine table with structure or it by default not possible.
From what you saying the answer is not possible if the two stucture are not same size.
(1x1) x (1x16) should be possible in all cases (ie. structure, arrays, etc.).
but (105x1) x (1x1) x (1x16) is not because table x struct x struct is not possible to give structure.
Well, the general answer to all of the above is "no, you can't do that" -- it makes no sense to even say it that way.
As far as EEG Lab, from the original Q? it appears the only reason for the question was you ran into an issue of how to build an input dataset that it will accept and your attempt by simply catenating dissimilar data structures you created doesn't work to get you there.
So, the way out of the impasse is NOT to continue to try to do the impossible in MATLAB but to understand what it is that the toolbox/app you're trying to use expects and then build your input to match its requirements.
But, you've given us no references to it; I'm sure it will have doc that will explain its input data structure and that it is possible to create what it needs, but understanding that will have to be the first step; this is non-fruitful direction you're trying in this thread.
ADDENDUM:
So, I DAQGS and found the .org website; it appears to be a very complex app as one might expect; I suggest you need to <begin here to see about importing data>, there appears to be a comprehensive set of steps outlined to follow, but it also doesn't appear there's a traditional MATLAB-like command line interface from an (extremely) quick perusal.
There is <an EEG Lab .set file that appears to be a composite object> but I can't find a definition of its structure. The command to save a .mat file as provided is syntax in MATLAB for the save command, but it doesn't help in explaining the content/form of that user structure that is being saved. That's got to exist somewhere, but like you, at the moment I'm confused as to what that format would be.
It appears you've built the individual structures per the above doc, but I also don't see how to combine them into the composite whole without more time than have to give at the moment.
I'm sure it's documented somewhere and probably if you look at the composite dataset used in the tutorial you could figure it out from a whos on that file, but it does seem like a fundamental concept that should be far more obvious than seems to be in the doc.
Clearly, there is a way to import the data structures into EEG Lab that doesn't require illegal MATLAB syntax that you're trying to use, but the answer is going to be in the EEG Lab community/documentation and probably not from the MATLAB Answers forum unless there does happen to be a regular here who also happens to use it, but I don't recall seeing specific EEG Lab question before so it's probably not likely.
"You can use [] to concatenate a table and a cell array:"
But only under the special circumstance the number of elements of the cell array is conformant with the height() of the table and oriented such that the row dimension matches. And then, what you really have done is to augment the table by adding a new variable column as Walter's example result shows.
"(1x1) x (1x16) should be possible in all cases (ie. structure, arrays, etc.)."
No. It would never be possible other than to combine the two whatevers as a cell array with each cell containing the corresponding object.
MATLAB objects are all regular and the only way any can be catenated is that the types and sizes are commensurate in all respects. Anything else other than stuffing disparate stuff into cells in a cell array is simply not possible.

note by the way that the [] operations does not support scalar expansion.

Sign in to comment.

Answers (1)

OK, I found where the tutorial <eeglab_data.set> had been uploaded to GitHub so could get a peek at it without downloading the entire package..
Answers won't let attach a file without the approved .mat extension, so I renamed to conform; it's still the same file content, just without the EEG Lab .set extension.
whos -file eeglab_dataset.mat
Name Size Bytes Class Attributes EEG 1x1 4048648 struct
So, it is a MATLAB struct -- that we probably had guessed...just what does it comprise of?
Let's load it and see...
load eeglab_dataset % can dispense with the "-mat" since is using the .mat
whos EEG % see what it is...
OK, it is just a single struct; which one of those defined we saw in the description?
EEG
Name Size Bytes Class Attributes EEG 1x1 4048648 struct
EEG = struct with fields:
setname: 'Continuous EEG Data' filename: 'eeglab_data.set' filepath: '' pnts: 30504 nbchan: 32 trials: 1 srate: 128 xmin: 0 xmax: 238.3047 data: [32×30504 single] icawinv: [] icasphere: [] icaweights: [] icaact: [] event: [1×154 struct] epoch: [] chanlocs: [] comments: [6×769 char] averef: 'no' rt: [] eventdescription: {[2×29 char] [2×63 char] [2×36 char] ''} epochdescription: {} specdata: [] specicaact: [] reject: [1×1 struct] stats: [1×1 struct] splinefile: [] ref: 'common' history: '' urevent: [1×154 struct]
So there ya' go...you don't append stuff; you put it in the .set .mat struct file as another member -- the chanlocs data here is an empty array; you would assign yours there, it would appear.
NOTA BENE: Some of the field content are themselves struct -- observe 'reject', 'stats', 'urevent'. Also note that 'urevent' is a struct array, not just a single struct. That's how they deal with the mismatch in sizes; EEG Lab has to know how to deal with these struct fields that are structs within the struct; you tell it what they are by adhering to the given naming convention for each.
I think there's a lot more flexibility to load individual defined structs than just loading a single .set file as the example uses, but it'll take learning your way around the package to find out all the ways things can be done.
But, you don't catenate stuff together as you were trying; that's just not legal MATLAB syntax for the most part except for the few specific things that can be made to match as Walter showed.

3 Comments

Curiosity and the cat...let's see what those other structs look like, too...
load eeglab_dataset
EEG.reject
ans = struct with fields:
rejjp: [] rejjpE: [] rejkurt: [] rejkurtE: [] rejmanual: [] rejmanualE: [] rejthresh: [] rejthreshE: [] rejfreq: [] rejfreqE: [] rejconst: [] rejconstE: [] icarejjp: [] icarejjpE: [] icarejkurt: [] icarejkurtE: [] icarejmanual: [] icarejmanualE: [] icarejthresh: [] icarejthreshE: [] icarejfreq: [] icarejfreqE: [] icarejconst: [] icarejconstE: [] rejglobal: [] rejglobalE: [] threshold: [0.8000 0.8000 0.8000] threshentropy: 600 threshkurtact: 600 threshkurtdist: 600 gcompreject: [1×0 double] rejmanualcol: [1 0.9116 0.6464] rejthreshcol: [0.8487 1 0.5008] rejconstcol: [0.6940 1 0.7008] rejjpcol: [1 0.6991 0.7537] rejkurtcol: [0.6880 0.7042 1] rejfreqcol: [0.9596 0.7193 1] disprej: {}
EEG.stats
ans = struct with fields:
jp: [] jpE: [] icajp: [] icajpE: [] kurt: [] kurtE: [] icakurt: [] icakurtE: [] compenta: [] compentr: [] compkurta: [] compkurtr: [] compkurtdist: []
EEG.urevent(1)
ans = struct with fields:
type: 'square' position: 2 latency: 129.0087
chanlocs = struct('labels', {data.Fp1,data.Fp2, data.F7, data.F3, data.F4, data.F8, data.T3, data.C3, data.C4,data.T4, data.T5, data.P3, data.P4, data.T6, data.O1, data.O2}, ...
'type', {'EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG'}, ...
'ref', {char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty}, ...
'theta', {-18, 18,-54,-39,39,54,-90,-90,90,90,-126,-141,141,126,-162,162}, ...
'radius', {0.511,0.511,0.511,0.333,0.333,0.511,0.511,0.256,0.256,0.511,0.511,0.333,0.333,0.511,0.511,0.511}, ...
'X', {0.95,0.95,0.587,0.673,0.673,0.587,6.12e-17,4.4e-17,4.4e-17,6.12e-17,-0.587,-0.673,-0.673,-0.587,-0.95,-0.95}, ...
'Y', {0.309,-0.309,0.809,0.545,-0.545,-0.809,0,0.719,-0.719,0,0.809,0.545,-0.545,-0.809,0.309,-0.309}, ...
'Z', {-0.0349,-0.0349,-0.0349,0.5,0.5,-0.0349,0.999,0.695,0.695,-0.999,-0.0349,0.5,0.5,-0.0349,-0.0349,-0.0349}, ...
...
NOTA BENE: In the description of the EEG (.set file) struct with its fields of data including sub-structs like chanlocs, the data are all shown as normal MATLAB numeric arrays, NOT cell arrays. I think you'll need to convert your generation code to use [] instead of {} for the numeric data.
chanlocs = struct('labels', {data.Fp1,data.Fp2, data.F7, data.F3, data.F4, data.F8, data.T3, data.C3, data.C4,data.T4, data.T5, data.P3, data.P4, data.T6, data.O1, data.O2}, ...
'type', {'EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG', 'EEG','EEG','EEG'}, ...
'ref', {char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty,char.empty}, ...
'theta', [-18, 18,-54,-39,39,54,-90,-90,90,90,-126,-141,141,126,-162,162], ...
'radius', [0.511,0.511,0.511,0.333,0.333,0.511,0.511,0.256,0.256,0.511,0.511,0.333,0.333,0.511,0.511,0.511], ...
'X', [0.95,0.95,0.587,0.673,0.673,0.587,6.12e-17,4.4e-17,4.4e-17,6.12e-17,-0.587,-0.673,-0.673,-0.587,-0.95,-0.95], ...
'Y', [0.309,-0.309,0.809,0.545,-0.545,-0.809,0,0.719,-0.719,0,0.809,0.545,-0.545,-0.809,0.309,-0.309], ...
'Z', [-0.0349,-0.0349,-0.0349,0.5,0.5,-0.0349,0.999,0.695,0.695,-0.999,-0.0349,0.5,0.5,-0.0349,-0.0349,-0.0349], ...
...
etc., ...
Read through that description of the EEG and ALLEEG struct in the doc CAREFULLY, looking at the examples shown of sample inputs.
It actually is the Hansel and Gretel trail of breadcrumbs through the forest that gives the needed format to use and the other tutorial file (that I didn't find a link to other than downloading the whole enchilada) is more complex and has these substructs populated for examples.
I see that there are more complicated input patterns discussed using the other tutorial file in line in the discussion that illustrate chanlocs struct being in EEG struct, etc., ...
Once one finally gets to the details, it is pretty straightforward; the ".set" file is just a MATLAB .mat file containing the EEG struct as outlined. Although it appears it can also be saved/read as two files; one the metadata and a second that contains the actual raw data.
Note:
When you use struct() and the data portion associated with a fieldname is a cell array, then struct() creates one structure member for each element of the cell array, with each element of the cell array in turn being assigned as the member contents. When you use a non-cell then the contents are copied to every struct member.
Example,
out = struct('labels', {'ABC', 'DEF'}, 'X', [1 2 3])
out = 1×2 struct array with fields:
labels X
out(1)
ans = struct with fields:
labels: 'ABC' X: [1 2 3]
out(2)
ans = struct with fields:
labels: 'DEF' X: [1 2 3]
This can lead to code such as
Xvals = [0.95,0.95,0.587,0.673,0.673,0.587,6.12e-17,4.4e-17,4.4e-17,6.12e-17,-0.587,-0.673,-0.673,-0.587,-0.95,-0.95];
Yvals = [0.309,-0.309,0.809,0.545,-0.545,-0.809,0,0.719,-0.719,0,0.809,0.545,-0.545,-0.809,0.309,-0.309];
Zvals = [-0.0349,-0.0349,-0.0349,0.5,0.5,-0.0349,0.999,0.695,0.695,-0.999,-0.0349,0.5,0.5,-0.0349,-0.0349,-0.0349];
thvals = [-18, 18,-54,-39,39,54,-90,-90,90,90,-126,-141,141,126,-162,162];
rvals = [0.511,0.511,0.511,0.333,0.333,0.511,0.511,0.256,0.256,0.511,0.511,0.333,0.333,0.511,0.511,0.511];
N = length(Xvals);
chanlocs = struct('labels', {data.Fp1, data.Fp2, data.F7, data.F3, data.F4, data.F8, data.T3, data.C3, data.C4,data.T4, data.T5, data.P3, data.P4, data.T6, data.O1, data.O2}, ...
'type', repmat({'EEG'}, 1, N), ...
'ref', repmat({''}, 1, N), ...
'theta', num2cell(thvals), ...
'radius', num2cell(rvals), ...
'X', num2cell(Xvals), ...
'Y', num2cell(Yvals), ...
'Z', num2cell(Zvals))
Unable to resolve the name 'data.Fp1'.

Sign in to comment.

Categories

Products

Release

R2019b

Community Treasure Hunt

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

Start Hunting!