diff --git a/doc/dynare.texi b/doc/dynare.texi index fb60a65d1..0b5cfe0dd 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -4334,12 +4334,14 @@ univariate convergence diagnostic. @item datafile = @var{FILENAME} @anchor{datafile} -The datafile: a @file{.m} file, a @file{.mat} file, a @file{.csv} file, or a -@file{.xls}/@file{.xlsx} file (the latter format is supported under Octave -if the @uref{http://octave.sourceforge.net/io/,io} and -@uref{http://octave.sourceforge.net/java/,java} packages from -Octave-Forge are installed, along with a -@uref{http://www.java.com/download,Java Runtime Environment}) +The datafile: a @file{.m} file, a @file{.mat} file, a @file{.csv} +file, or a @file{.xls}/@file{.xlsx} file (under Octave, the +@uref{http://octave.sourceforge.net/io/,io} from Octave-Forge is +required for the @file{.csv}, @file{.xls} and @file{.xlsx} formats; in +addition, for the @file{.xls} and @file{.xlsx} formats, the +@uref{http://octave.sourceforge.net/java/,java} package is required, +along with a @uref{http://www.java.com/download,Java Runtime +Environment}) @item xls_sheet = @var{NAME} @anchor{xls_sheet} diff --git a/matlab/load_csv_file_data.m b/matlab/load_csv_file_data.m index 34985c208..7317ca330 100644 --- a/matlab/load_csv_file_data.m +++ b/matlab/load_csv_file_data.m @@ -1,18 +1,20 @@ -function [freq, init, data, varlist] = load_csv_file_data(file, withtime, withnames, noemptycell) +function [freq, init, data, varlist] = load_csv_file_data(file) % Loads data in a csv file. % % INPUTS % o file string, name of the csv file (with path). -% o withtime integer scalar, nonzero iff the first column is for the dates of the observations. -% o withnames integer scalar, nonzero iff the first row is for the names of the variables. -% o noemptycell integer scalar, nonzero the csv file does not have empty cells. % % OUTPUTS % o freq integer scalar equal to 1, 4, 12 or 52 (for annual, quaterly, monthly or weekly frequencies). % o init dates object, initial date in the dataset. % o data matrix of doubles, the data. % o varlist cell of strings, names of the variables. +% +% REMARKS +% The varlist output will be set only if the first line contains variable +% names. Similarly, if the first column does not contain dates, then +% freq will be 1 and init will be year 1. % Copyright (C) 2012-2013 Dynare Team % @@ -31,174 +33,45 @@ function [freq, init, data, varlist] = load_csv_file_data(file, withtime, withna % You should have received a copy of the GNU General Public License % along with Dynare. If not, see . -% Set defaults. -if nargin<4 - noemptycell = 1; - if nargin<3 - withnames = 1; - if nargin <2 - withtime = 1; - if nargin<1 - error('load_csv_file_data:: I need at least one input (name of the csv file)!') - end - end - end -end - -if ~withtime && ~withnames && noemptycell - % Use matlab builtin routine! - data = csvread(file); -end - -if ~( isequal(withtime,0) || isequal(withtime,1) ) - error('load_csv_file_data:: Second input argument has to be equal to 1 or 0!') -end - -if ~( isequal(withnames,0) || isequal(withnames,1) ) - error('load_csv_file_data:: Third input argument has to be equal to 1 or 0!') -end - % Output initialization freq = 1; % Default frequency is annual. init = dates(1,1); % Default initial date is year one. varlist = []; -if ~isoctave - % Under Matlab, save time by using importdata - assert(exist(file, 'file') == 2, ['load_csv_file_data: I can''t find file ' file '!']); - A = importdata(file, ',', withnames); - if withnames && withtime - if size(A.textdata, 1) == 1 - % year dates confused for data - varlist = A.textdata(1, 2:end); - init = dates([num2str(A.data(1, 1)) 'Y']); - data = A.data(:, 2:end); - else - varlist = A.textdata(1, 2:end); - init = dates(A.textdata{2, 1}); - data = A.data; - end - elseif withnames && ~withtime - varlist = A.textdata; - data = A.data; - elseif ~withnames && withtime - if ~isstruct(A) - % year dates confused for data - init = dates([num2str(A.data(1, 1)) 'Y']); - data = A(:, 2:end); - else - init = dates(A.textdata{1, 1}); - data = A.data; - end + +assert(exist(file, 'file') == 2, ['load_csv_file_data: I can''t find file ' file '!']); + +if isoctave + if ~user_has_octave_forge_package('io') + error('The io package is required to read CSV files from Octave') + end + A = csv2cell(file); + [data, T, L] = parsecell(A); + withvars = L.numlimits(2,1) > L.txtlimits(2,1); + withtime = L.numlimits(1,1) > L.txtlimits(1,1); +else + A = importdata(file); + if ~isstruct(A) + data = A; + T = {}; + withvars = 0; + withtime = 0; else - error('load_csv_file_data:: Shouldn''t arrive here'); + data = A.data; + T = A.textdata; + % importdata() allows text only at the top and the left, so the following + % tests are sufficient. + withvars = size(T, 2) >= size(data, 2); + withtime = size(T, 1) >= size(data, 1); end - freq = init.freq; - varlist = transpose(varlist); - return end -% Check if file exists. -if check_file_extension(file,'csv') - try - fid = fopen(file,'r'); - catch - error(['load_csv_file_data: I can''t find file ' file '!']) - end -else - error('load_csv_file_data: Wrong file extension!') +if withvars + varlist = T(1, 2:end); + T = T(2:end, :); end - -% bfile contains a vector of ascii codes. -bfile = fread(fid); - -% Close (csv) file. -fclose(fid); - -% Set newline code (ok for *nix, check for mac and windows) -if isunix - newline_code = 10; -elseif ispc - newline_code = 13; -elseif ismac - newline_code = 10; -else - error('load_csv_file_data:: Not implemented for your OS!') -end - -% Get the positions of the end-of-line code; -end_of_line_locations = find(bfile==newline_code); -if ispc && isempty(end_of_line_locations) - newline_code=10; - end_of_line_locations = find(bfile==newline_code); -end; -tmp = find(bfile==newline_code); - -% Get the number of lines in the file. -ndx = length(tmp); - -% Create a cell of indices for each line. -b = [1; end_of_line_locations+1]; -c = [end_of_line_locations-1; length(bfile)+1]; -b = b(1:end-1); -c = c(1:end-1); - -linea = 1; - -if withnames - % Get the first line of the csv file (names of the variables). - linee = char(transpose(bfile(b(linea):c(linea)))); - % Get the content of the first line and determine the number of variables and their names. - [B,C] = get_cells_id(linee,','); - if withtime - B = B(2:end); - C = C(2:end); - end - varlist = cell(length(B),1); - number_of_variables = length(varlist); - for i=1:number_of_variables - varlist(i) = {linee(B(i):C(i))}; - end - varlist = strtrim(varlist); - linea = linea+1; -end - -% Get following line (number 1 or 2 depending on withnames flag) -linee = char(transpose(bfile(b(linea):c(linea)))); -comma_locations = transpose(strfind(linee,',')); -B = 1; -C = comma_locations(1)-1; - if withtime - tmp = linee(B:C); - % Check the dates formatting - if isnumeric(tmp) && isint(tmp) - tmp = [num2str(tmp) 'Y']; - end - if ~isdate(tmp) - error('load_csv_file_data:: Formatting error. I can''t read the dates!') - end - init = dates(tmp); + init = dates(T{1, 1}); freq = init.freq; - first = 2; -else - first = 1; end -if ~withnames - number_of_variables = length(tmp)-withtime; -end - -% Initialization of matrix data. -data = zeros(ndx,number_of_variables); - -% Populate data. -for linea = 1+withnames:ndx - linee = char(transpose(bfile(b(linea):c(linea)))); - [B,C] = get_cells_id(linee,','); - for i=first:length(B) - data(linea,i-withtime) = str2double(linee(B(i):C(i))); - end -end - -% Remove first line if withnames -data = data(1+withnames:ndx,:); \ No newline at end of file +varlist = transpose(varlist);