indexing - Workaround for dynamically generating a structure - Matlab/Octave issues -


i have many, many sets of data in .csv format i've organized file name standard can use regular expressions second time ever. have, however, run slight problem. data files titled things like, "2012001_c335_2000mhz_p_1111.csv". there 4 years of interest, 2 frequencies, , 4 different c335-style labels describe locations. have significant amount of data processing on each of these files, i'd read them 1 giant structure , processing on different parts of it. i'm writing:

for ix_id = 1:length(ids)  ix_years = 1:2:length(ids_years{ix_id})   ix_frq = 1:length(frqs)    st = [ids_years{ix_id}{ix_year} '_' ids{ix_id} '_' ids_frqs{ix_id}{ix_frq}'_p_1111.csv'];    data.(ids_frqs{ix_id}{ix_frq}).(ids{ix_id}).(['y' ids_years{ix_id}{ix_year}]) =...         dlmread(st);   end  end end 

all ids variables 1x4 cell arrays each cell contains strings.

this produces errors: "error: cs-list cannot further indexed" , "error: invalid assignment cs-list outside multiple assignment"

i did internet search these errors , found few posts dates ranging 2010 2012, such this one , this one, author suggests it's problem octave itself. can workaround involves defining 2 separate structures removing innermost loop on ix_frq , replacing lines beginning "st" , "data" with

data.1500.(ids{ix_id}).(['y' ids_years{ix_id}{ix_year}]) = ...   dlmread([ids_years{ix_id}{ix_year} '_' ids{ix_id} '_' ids{ix_id} '_1500mhz_p_1111.csv']); data.2000.(ids{ix_id}).(['y' ids_years{ix_id}{ix_year}]) = ...   dlmread([ids_years{ix_id}{ix_year} '_' ids{ix_id} '_' ids{ix_id} '_2000mhz_p_1111.csv']); 

so seems trouble arises when try make more nested structure. i'm wondering if unique octave or same in matlab, , if there's slicker workaround defining 2 separate structures since i'd portable possible. if have insight meaning of error message, i'm interested in too. thanks!

edit: here full script - generates few dummy .csv files. runs on octave v. 3.8

clear %this program tests creation of various structures.  end goal have structure of format frequency.beamname.year(1) = matrix of appropriate file = rand(3,2); csvwrite('2009103_c115_1500mhz.csv',a) csvwrite('2009103_c115_2000mhz.csv',a) csvwrite('2010087_c115_1500mhz.csv',a) csvwrite('2010087_c115_2000mhz.csv',a) csvwrite('2009103_c335_1500mhz.csv',a) csvwrite('2009103_c335_2000mhz.csv',a) csvwrite('2010087_c335_1500mhz.csv',a) csvwrite('2010087_c335_2000mhz.csv',a)  data = dir('*.csv');  %imports of files of directory files = {data.name};  %cell array of filenames nfiles = numel(files);  %find years years = unique(cellfun(@(x)x{1},regexp(files,'\d{7}','match'),'uniformoutput',false));   %find beam names ids = unique(cellfun(@(x)x{1},regexp(files,'([c-i]\d{3})|([c-i]\d{1}[c-i]\d{2})','match'),'uniformoutput',false)); %find frequencies frqs = unique(cellfun(@(x)x{1},regexp(files,'\d{4}mhz','match'),'uniformoutput',false));  %now, vectorize cover beams id_ix = 1:length(ids)   expression_yrs = ['(\d{7})(?=_' ids{id_ix} ')'];   listl_yrs = regexp(files,expression_yrs,'match');   ids_years{id_ix} = unique(cellfun(@(x)x{1},listl_yrs(cellfun(@(x)~isempty(x),listl_yrs)),'uniformoutput',false));  %returns years data collected both 1500 , 2000 mhz antennas along each of thebeams   expression_frqs = ['(?<=' ids{id_ix} '_)(\d{4}mhz)'];    listfrq = regexp(files,expression_frqs,'match'); %finds every frequency collected c115, c335   ids_frqs{id_ix} = unique(cellfun(@(x)x{1},listfrq(cellfun(@(x)~isempty(x),listfrq)),'uniformoutput',false)); end  %% finally, dynamically generate structure data.beam.year.frequency %this works ix_id = 1:length(ids)   ix_year = 1:length(ids_years{ix_id})     data1500.(ids{ix_id}).(['y' ids_years{ix_id}{ix_year}])=dlmread([ids_years{ix_id}{ix_year} '_' ids{ix_id} '_' ids_frqs{1}{1} '.csv']);     data2000.(ids{ix_id}).(['y' ids_years{ix_id}{ix_year}])=dlmread([ids_years{ix_id}{ix_year} '_' ids{ix_id} '_' ids_frqs{1}{2} '.csv']);   end end  %this doesn't work ix_id=1:length(ids)   ix_year=1:length(ids_years{ix_id})     ix_frq = 1:numel(frqs)         data.(['f' ids_frqs{ix_id}{ix_frq}]).(ids{ix_id}).(['y' ids_years{ix_id}{ix_year}])=dlmread([ids_years{ix_id}{ix_year} '_' ids{ix_id} '_' ids_frqs{ix_id}{ix_frq} '.csv']);     end    end end 

hopefully, helps clarify question - not sure of etiquette here posting edits , code.

the problem when loop causing problem, data exists , struct array.

octave> data data =    8x1 struct array containing fields:      name     date     bytes     isdir     datenum     statinfo 

when select field struct array cs-list (comma-separate list) unless index of structs in struct array. see:

octave> data.name ans = 2009103_c115_1500mhz.csv ans = 2009103_c115_2000mhz.csv ans = 2009103_c335_1500mhz.csv ans = 2009103_c335_2000mhz.csv ans = 2010087_c115_1500mhz.csv ans = 2010087_c115_2000mhz.csv ans = 2010087_c335_1500mhz.csv ans = 2010087_c335_2000mhz.csv octave> data(1).name ans = 2009103_c115_1500mhz.csv 

so when do:

data.(...) = dlmread (...); 

you don't expecting on left hand side, cs-list. i'm guessing accidental, since data @ moment has filenames, create new empty struct:

data = struct (); # clear previous data ix_id=1:length(ids)   ix_year=1:length(ids_years{ix_id})     ix_frq = 1:numel(frqs)         data.(['f' ids_frqs{ix_id}{ix_frq}]).(ids{ix_id}).(['y' ids_years{ix_id}{ix_year}])=dlmread([ids_years{ix_id}{ix_year} '_' ids{ix_id} '_' ids_frqs{ix_id}{ix_frq} '.csv']);     end    end end 

i recommend think better current solution. code looks overcomplicated me.


Comments