SAVE command: How to specify the variable to be saved if it is a variable inside an array. assignin has been used to create the variable from a string in an array.

7 visualizaciones (últimos 30 días)
Thank you again for your help.
I am downloading several FED bond data series. The data is returned in a 21 x 11 structure. The 21 rows each represent a different series of data. Columns 1 through 10 are single valued of different types. Column 11 is a nested array of two double values representing a date number and an interest rate in percent. I must put each of the column 11 nested arrays in a separate file because each of the 21 nested arrays may have different numbers of rows.
In order to create the 21 files, one for each of the data series, I am using a for loop with variable x defined inside the loop to hold the data as I massage it to a timetable for saving. I am using the save command to write the .mat files. The names of the .mat files are taken from a string array that defines filenames. This method results in each of the files having a name associated with one of the FED data series but the variable associated with the data in each file is named x. This will cause the need for extra work to redefine the variable name when the data is loaded for analysis.
In researching how to force each of the data series to have a variable name equal to the filename without extension, I have read many warnings about not defining variables on the fly, not to use eval, and just don't do this and stop asking questions as to how to create variables on the fly. Then I found the assignin function which does assign values to variables defined as strings.
The save command requires that the variable to be saved be specified as a string value if using the normal syntax, or as a valid variable name if using the command syntax.
The variables created by the assignin command as I am using it are not consistent with what the save command wants. The assignin command appears to work properly in side tests using abbreviated forms of my input data below. The save command does not accept referencing the array having the variable name after the value held by loop variable x is assigned to the variable within the array.
If I am not able to use the loop method to move through the structure and extract the data from column 11, I will have to repeat the commands in the loop for each of 21 independent calls for one data series each. I feel that I must be missing something really simple because to have to resort to 21 individual data calls each having 3 lines of code and a save command is real ugly. I don't think Matlab is that crude.
I have put some code below that works for you to see the structure that is returend. The FED data is freely avaliable. The lines using the assignin command and its associated save are commented out as they fail.
FEDseriesIDs = {'DGS1MO','DGS3MO','DGS6MO','DGS1','DGS2','DGS3','DGS5'...
,'DGS7','DGS10','DGS20','DGS30','DFII5','DFII7','DFII10','DFII20'...
,'DFII30','DLTIIT','DTB4WK','DTB3','DTB6','DTB1YR'};
fileNames = {'US_1M', 'US_3M', 'US_6M', 'US_1Y', 'US_2Y', 'US_3Y'...
, 'US_5Y', 'US_7Y', 'US_10Y' , 'US_20Y','US_30Y', 'US_5Y_ii'...
, 'US_7Y_ii', 'US_10Y_ii', 'US_20Y_ii', 'US_30Y_ii', 'T_LTA'...
, 'US_4WK_T_bill', 'US_3M_T_bill', 'US_6M_T_bill', 'US_1Y_T_bill'};
dataDirectory = 'E:\US Bonds';
% Variables for fetching data
startDate = '01/01/2000';
endDate = datestr(today-1);
connection = fred('https://fred.stlouisfed.org/');
connection.DataReturnFormat = 'timetable';
connection.DatetimeType = 'datetime';
% The fetch command returns a 21 x 11 table. The 11th column contains two
% double values in nested cells: Date and % (interest rate). The 2nd
% column contains a string that is the FED series ID for the row of data.
% The number of rows in each set of nested cells in the 11th column are not
% equal. Each set of nested cells needs to be converted to a timetable and
% saved to a file for ease of use of data in downstream analysis.
rawData = fetch(connection,FEDseriesIDs,startDate,endDate);
% The code below modifies rawData to extract the data only in the 11th
% column and provides column names.
rawData = cell2table(rawData.Data);
j = length(fileNames);
for i = 1:j
x = splitvars(table(rawData.Var1{i,1}));
x.Properties.VariableNames = {'Date','Interest Rate, %'};
x = table2timetable(x);
save(strcat(dataDirectory,'\',string(fileNames(i)),'.mat'),'x','-v7.3') ;
% assignin('base',fileNames{i},x)
% save(strcat(dataDirectory,'\',string(fileNames(i)),'.mat'), fileNames{i}, '-v7.3' ;
end
% Clear variables created by this function
clear FEDseriesIDs fileNames dataDirectory startDate endDate connection rawData j x ;
  1 comentario
Stephen23
Stephen23 el 14 de Oct. de 2019
Editada: Stephen23 el 14 de Oct. de 2019
"This will cause the need for extra work to redefine the variable name when the data is loaded for analysis"
I doubt that. In reality it is much simpler and more efficient to write code when multiple .mat files contain exactly the same variable names. Also note that meta-data is data, and data belongs in variables and not in variable names: consider for example, what your code will do if one of the fileNames is not a valid MATLAB variable name.
You could easily avoid the entire messy situation by storing the meta-data in a variable.
Also note that for constructing filenames fullfile is preferred over string concatenation.

Iniciar sesión para comentar.

Respuesta aceptada

Stephen23
Stephen23 el 14 de Oct. de 2019
Editada: Stephen23 el 14 de Oct. de 2019
save using the structure syntax:
S = struct('theNameYouWant',x);
save(...,'-struct','S')
  1 comentario
Mark Smith
Mark Smith el 14 de Oct. de 2019
Editada: Mark Smith el 14 de Oct. de 2019
I accept your answer. It works and it is as elegant as I expect Matlab to be. I also am grateful for the pointer to the fullfile command. Thank you.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Scope Variables and Generate Names en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by