I have created a script to create ~300 variable names in my workspace. I need to save these .mat files to .txt files - is there any way to call these variables in some sort of loop or just save them all at once to .txt files?
They are all cells of varying size, about 1000x5 on average.
The first row of the data contains strings, the other elements are all non integer numbers.
Here is an example of one of the .mat files-
http://www.yourfilelink.com/get.php?fid=1065782
I don't know a whole lot about Matlab so any help would be really appreciated! Thank you.
A possible solution could be:
to load the .matfiles through a loop (the name of the file can be either dynamically generated or read from a list)
to extract the first row of the cellarray (the string) and write it in a .txt file by using the dlmwrite function
to remove the first row and write (again with dlmwrite) the numerical values in the .txt having converted them using the cell2mat function.In the writing of the numerical values, the precision has to carefully set.
file_name_root='x2413';
% dummy loop (one iteration) just to test dynamic filename generation
for i=3:3
% generate the name of the input file
input_file_name=[file_name_root int2str(i)];
% generate the name of the output file
output_file_name=[file_name_root int2str(i) '.txt'];
% extract the name of the cellarray and assign it to "the_cell" variable
tmp=load(input_file_name);
var_name=char(fieldnames(tmp));
eval(['the_cell=tmp.' var_name ';'])
[r,c]=size(the_cell);
str='';
% get the first row string (probably a cleaver way to do it exists)
for i=1:c
str=[str ' ' char(the_cell(1,i))];
end
% print the first row in a ".txt" file
dlmwrite(output_file_name,sprintf('%s',str),'delimiter','')
% remove the first row
the_cell(1,:)=[];
% write the numerical values in the ".txt" file
% the "precision" shall be carefully set
dlmwrite(output_file_name,cell2mat(the_cell),'precision','%13.9f','delimiter',' ','-append')
end
Related
This question already exists:
Generating vectors from multiple matrices
Closed 6 years ago.
I am really new in matlab. So i am trying to learn the very basics. I have 8 tsv files with names like 2004.07.01.0000.tsv, 2004.07.01.0300.tsv, where each file has 72 rows and 144 columns. I am trying to automatically import all of those files to matlab in a matrix form to calculate the mean, median, skewness (for data correction). What I did is that I imported one file (2004.07.01.0000.tsv) using matlab gui, then I generated a function called importfile. I am trying to use a for loop to access all the data in those files but I could not figure it out. I tried (not sure at all):
for fileNum=1:8;
startRow=1;
endRow=72;
filename
a=importfile(filename, startRow, endRow);
end
If your importfile() function works correctly, in this manner at every for-loop iteration you'll overwrite a with the most recent imported file. You should concatenate all your files (i.e. matrices) instead.
A matrix concatenation can either be done by rows (i.e. horizontal concatenation) or by columns (i.e. vertical concatenation). As I understand, you want a vertical concatenation in order to generate a unique matrix with 144 columns and as many rows as your single files contain.
Thus you should change the loop as follows
myMatrix=[];
for fileNum=1:8;
startRow=1;
endRow=72;
filename
myMatrix=[myMatrix ; importfile(filename, startRow, endRow)];
end
The vertical concatenation can be done by means of the ; operator, thus an instruction like A=[B ; C] will create a matrix A by concatenating matrices B and C. In your case you initialize myMatrix as empty and then you will vertically concatenate (in an iterative fashion) all outputs from importfile(), that are your .tsv files.
At the end of the loop, myMatrix should have size NxM where M is 144 and N is the sum of the number of rows across all your files (8*72).
Update
If you have to pass explicitly the filename to the importfile() function you can create a cell array of strings in which each element of the cell is a filename. Thus in our case the cell array will be something like:
filenames={'filename1.tsv','filename2.tsv',...,'filename8.tsv'};
obviously you must replace the strings inside the cell with the proper filenames and finally you can slightly edit the loop as follows
myMatrix=[];
for fileNum=1:8;
startRow=1;
endRow=72;
myMatrix=[myMatrix ; importfile(filenames{i}, startRow, endRow)];
end
In this manner, at every loop iteration the i-th filename will be given as input to importfile() and hopefully it'll be loaded.
For this to work you should (let's make things simple)
place your Matlab script and obviously the function importfile() in the same folder containing your .tsv files
set said folder as the Current Folder
or if you have the .tsv files in a given folder and your scripts in another folder, then the Current Folder must certainly will be the folder containing your scripts and the filenames inside the cell array filenames must contain the entire path, not just the proper filenames.
I am performing a simulation many many times, and would like to store the result in a csv file.
I could just save the results in an array and write the array to a csv, but the array would be very large and a big strain on my system.
I was thinking it could be easier to simulate, save the result of one simulation in a csv, complete a new simulation, and then store the new result in the second line of the csv.
How can I write csv lines one by one in matlab?
Easy, use: dlmwrite(filename,M,'-append')
For example:
simulation_results = [1,2,3,4]
dlmwrite('C:\<Your Directory Path>\simulaton_results.csv', simulation_results, '-append');
This will append the simulation_results matrix to the end of the file you specify. The default delimiter is a comma ... perfect for writing csv files.
Try fprintf
%save to file
%save using fprintf function
fid_out = fopen('file_out.csv','w'); %open file and create fid
%save tab-separated column headers
%define column format and names and save to file
fprintf(fid_out,'%s\t%s\t%s\t%s\n','a_name','b_name','c_name','d_name');
%save tab-separated columns of data
for i = 1:size(data,1) %loop trough each line of each data variable and save to file line by line
%define column format and date to be saved.
%use () for numeric data, and {} for strings
fprintf(fid_out,'%s\t%s\t%d\t%.5f\n',a{i},b{i},c(i),d(i));
end
fclose(fid_out); %close file
%NOTE: fprintf cannot save structured data
I have 100 data files in a folder called "Experiment1", and I need to take all of the data from them and put them into a single matrix. Each data file contains 15 columns and 40 rows of data.
The order in which the files are in the folder is arbitrary. It doesn't matter in what order they get put into the combined matrix.
I've written some code using dlmread that will do the job:
for i = 1:100
%% Read in the relevant file.
filename = ['File_' int2str(i) '.dat']
Data = dlmread(fullfile(pwd, 'Experiment1',filename));
%% Put all the data I need in a separate matrix
NeededData(1+((i-1)*40):i+((i-1)*40)-i+40,1:15) = Data(:,1:15);
end
However, there are two things I don't like about my code.
The files have random names at present, and I'd need to manually change all their names to "File_1.dat", "File_2.dat", etc.
The code is cumbersome and hard to read.
How could I do things better?
Since you've fixed the problem of defining the name of the files to be read with dir, you can improve the way you add the read data (Data) to the output matrix (NeededData).
You can sumultaneously read the input files and add the data to the output matrix by inserting the call to dlmread directly in the assignment statement:
files=dir('*.dat');
n_files=length(files)
% Initialize the output matrix as empty
NeededData_0=[]
for i=1:n_files
% Simultaneously read input file and assign data to the output matrinx
NeededData_0=[NeededData_0;dlmread(files(i).name)]
end
In case you prefer working with the inides (as in your origina approach), since you know in advance that all the files have the same (40) number of rows) you can simplify the notation as follows:
files=dir('*.dat');
n_files=length(files)
% Define the number of rows in each inout file
n_rows=40;
% Define the number of colums in each inout file
n_col=15;
NeededData_2=nan(n_rows*n_files,n_col)
% Define the sequence of rows
r_list=1:n_rows:n_rows*n_files
for i=1:3
Data=dlmread(files(i).name)
NeededData_2(r_list(i):r_list(i)+n_rows-1,:)=Data
end
Hope this helps.
Using the suggestion to use dir present in the answers I have made the following code, which is clearly an improvement on my earlier effort. I would welcome further improvements, or suggestions for alternative approaches.
files = dir('*.dat');
for i = 1:length({files.name})
%% Read in the relevant file.
Data = dlmread(files(i).name);
%% Put all the data I need in a separate matrix
NeededData(1+((i-1)*40):i+((i-1)*40)-i+40,1:15) = Data(:,1:15);
end
I have a variable 'b'. Inside of b, I have 27X1 cell. In every cell there is some characters for example in 1x1 there is asdf, in 2x1 there is dfgh it's going on like this. I want that matlab creates mat files which names are asdf, dfgh and assign scalar valurs to these files. Could you help me please?
You might have a loop going through the "b"cellarray containing the "filenames" and:
1)get the filename by converting the content of the i-th to a string by using "char" function
2)call "save" specifying the filename (see previous point) and the list of scalar you want to save in it (in the question you did not specified which scalar to be saved)
% Generation of cellarray
b{1,1}='asdf'
b{2,1}='dfgh'
b{3,1}='third_mat_file'
% Loop through cellarray
for i=1:length(b)
% Get the filename
a=char(b(i))
% Generate a dummy scalar to be saved
m=rand;
% Save the scalar in the ".mat" file
save(a,'m')
end
Hope this helps.
I need to read a txt dataset and do some analytics by matlab. the structure of the txt file is like this:
ID Genre AgeScale
1 M 20-26
2 F 18-25
So, I want to load this txt file and build a matrix. I was wondering if someone could help me with this. I used fopen function but it gives me a single array not a matrix with 3 columns.
MATLAB has an interactive data importer. Just type uiimport in the command window. It allows you to:
Name the variable based on heading as shown in your example. You can also manually change them.
Specify variable (column) type, e.g. numeric, cell array of strings, etc.
Auto generate an import script for next use (if desired)
If it works for you then congratulations, you don't need to waste hours to write an data import script :)
Function fopen only returns the file ID and not the content of the file. Once you open the file you use the file ID to read line by line and then parse each line with strsplit using space as the delimiter.
Here's one simple way of doing so:
fid = fopen('textfile.txt');
tline = fgetl(fid);
n = 1;
while ischar(tline)
data(n,:) = strsplit(tline(1:end-1),' ');
n=n+1;
tline = fgetl(fid);
end
fclose(fid);
Keep in mind that the matrix data is type string and not numeric, so if you want to use the numeric values of your dataset, you'll need to take a look at the functions str2num (str2double in newer versions) and strtok to split the AgeScale strings with delimiter '-'.