writetable without dimension names - matlab

I'm trying to write a CSV from a table using writetable with writetable(..., 'WriteRowNames', true), but when I do so, Matlab defaults to putting Row in the (1,1) cell of the CSV. I know I can change Row to another string by setting myTable.Properties.DimensionNames{1} but I can't set that to be blank and so it seems like I'm forced to have some text in that (1,1) cell.
Is there a way to leave the (1,1) element of my CSV blank and still write the row names?

There doesn't appear to be any way to set any of the character arrays in the 'DimensionNames' field to either empty or whitespace. One option is to create your .csv file as you do above, then use xlswrite to clear that first cell:
xlswrite('your_file.csv', {''}, 1, 'A1');
Even though the xlswrite documentation states that the file argument should be a .xls, it still works properly for me.

Another approach could use memmapfile to modify the leading bytes of the file in memory.
For example:
% Set up data
LastName = {'Smith';'Johnson';'Williams';'Jones';'Brown'};
Age = [38;43;38;40;49];
Height = [71;69;64;67;64];
Weight = [176;163;131;133;119];
BloodPressure = [124 93; 109 77; 125 83; 117 75; 122 80];
T = table(Age, Height, Weight, BloodPressure, 'RowNames', LastName);
% Write data to CSV
fname = 'asdf.csv';
writetable(T, fname, 'WriteRowNames', true)
% Overwrite row dimension name in the first row
% Use memmapfile to map only the dimension name to memory
tmp = memmapfile(fname, 'Writable', true, 'Repeat', numel(T.Properties.DimensionNames{1}));
tmp.Data(:) = 32; % Change to the ASCII code for a space
clear('tmp'); % Clean up
Which brings us from:
Row,Age,Height,Weight,BloodPressure_1,BloodPressure_2
Smith,38,71,176,124,93
Johnson,43,69,163,109,77
Williams,38,64,131,125,83
Jones,40,67,133,117,75
Brown,49,64,119,122,80
To:
,Age,Height,Weight,BloodPressure_1,BloodPressure_2
Smith,38,71,176,124,93
Johnson,43,69,163,109,77
Williams,38,64,131,125,83
Jones,40,67,133,117,75
Brown,49,64,119,122,80
Unfortunately not quite deleted, but it's a fun approach.
Alternatively, you can use MATLAB's low level file IO to copy everything after the row dimension name to a new file, then overwrite the original:
fID = fopen(fname, 'r');
fID2 = fopen('tmp.csv', 'w');
fseek(fID, numel(T.Properties.DimensionNames{1}), 'bof');
fwrite(fID2, fread(fID));
fclose(fID);
fclose(fID2);
movefile('tmp.csv', fname);
Which produces:
,Age,Height,Weight,BloodPressure_1,BloodPressure_2
Smith,38,71,176,124,93
Johnson,43,69,163,109,77
Williams,38,64,131,125,83
Jones,40,67,133,117,75
Brown,49,64,119,122,80

No, that is currently not supported. The only workaround I see is to use a placeholder as dimension name and to programmatically remove it from the file afterwards.

writetable(T,fileFullPath,'WriteVariableNames',false);
When specify 'WriteVariableNames' as false (default one is true), then the variable/dimension names will NOT be written in the output file.
Ref link: https://uk.mathworks.com/help/matlab/ref/writetable.html

Related

Read first line of CSV file that contains text in cells

I have a deco.csv file and I only want to extract B1 to K1 (20 columns of the first rows), i.e. Deco_0001 to Deco_0020.
I first make a pre-allocation:
names = string(20,1);
and what I want is when calling S(1), it gives Deco_0001; when calling S(20), it gives Deco_0020.
I have read through textscan but I do not know how to specify the range is first row and running from column 2 to column 21 of the csv file.
Also, I want save the names individually but what I have tried just save the first line in only one cell:
fid=fopen('deco.csv');
C=textscan(fid, '%s',1);
fclose(fid);
Thanks!
It's not very elegant, but this should work for you:
fid=fopen('deco.csv');
C=textscan(fid, '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s',1,'Delimiter',',');
fclose(fid);
S = cell(20,1);
for ii = 1:20
S{ii} = C{ii+1};
end

How do I read comma separated values from a .txt file in MATLAB using textscan()?

I have a .txt file with rows consisting of three elements, a word and two numbers, separated by commas.
For example:
a,142,5
aa,3,0
abb,5,0
ability,3,0
about,2,0
I want to read the file and put the words in one variable, the first numbers in another, and the second numbers in another but I am having trouble with textscan.
This is what I have so far:
File = [LOCAL_DIR 'filetoread.txt'];
FID_File = fopen(File,'r');
[words,var1,var2] = textscan(File,'%s %f %f','Delimiter',',');
fclose(FID_File);
I can't seem to figure out how to use a delimiter with textscan.
horchler is indeed correct. You first need to open up the file with fopen which provides a file ID / pointer to the actual file. You'd then use this with textscan. Also, you really only need one output variable because each "column" will be placed as a separate column in a cell array once you use textscan. You also need to specify the delimiter to be the , character because that's what is being used to separate between columns. This is done by using the Delimiter option in textscan and you specify the , character as the delimiter character. You'd then close the file after you're done using fclose.
As such, you just do this:
File = [LOCAL_DIR 'filetoread.txt'];
f = fopen(File, 'r');
C = textscan(f, '%s%f%f', 'Delimiter', ',');
fclose(f);
Take note that the formatting string has no spaces because the delimiter flag will take care of that work. Don't add any spaces. C will contain a cell array of columns. Now if you want to split up the columns into separate variables, just access the right cells:
names = C{1};
num1 = C{2};
num2 = C{3};
These are what the variables look like now by putting the text you provided in your post to a file called filetoread.txt:
>> names
names =
'a'
'aa'
'abb'
'ability'
'about'
>> num1
num1 =
142
3
5
3
2
>> num2
num2 =
5
0
0
0
0
Take note that names is a cell array of names, so accessing the right name is done by simply doing n = names{ii}; where ii is the name you want to access. You'd access the values in the other two variables using the normal indexing notation (i.e. n = num1(ii); or n = num2(ii);).

Insert String in a CSV file matlab

how do I insert a string into a csv file in matlab. i used this code to write some data and create my csv file:
and here is the output of the code:
I'm trying to insert some text in the first 2 columns before the numerical data..
thanks in advance :)
There are several approaches are possible here.
Let's take a look at some of them:
If you need to add string to your csv file.
For example, I create some csv file like your:
q = [1 2 3 4 5 6 7];
csvwrite('csvlist4.csv',q,2,0);
All troubles is to add some string to csv - it's because we need to combine numeric and text data. There are no good functions for it in Matlab except low levels:
c = 'some big text';
fid = fopen('csvlist4.csv','r+');
fprintf(fid,c);
How it works: the data in csv is an array. I put data in 3rd row, so first and second is an empty but they have ','. When you use fprintf it will replace this , with your text. So if text is too long it will overwrite your data.
How to avoid this?
Easiest way - is to do it with help of xlswrite function. For your example:
txt = cell(size(Q))
txt{1} = 'this is your text'
X = [txt; num2cell(Q)]
xlswrite('new.xlsx',X)
Result:
Important moment here: number of cell for text must be the same as your data. But I filled with the text only first cell in my example.
And the one more way: read csv file, modify it's data and write to csv:
csvwrite('csvlist4.csv',a,2,0);
m = csvread('csvlist4.csv');
fid = fopen('csvlist4.csv','w');
c = 'your text'
fprintf(fid, c); fprintf(fid, '\n');
fclose(fid);
dlmwrite('csvlist4.csv', m(3:end,:), '-append');
Of course you can use cell array instead c and so on and so on.
Hope it helps!

Reading and Writing Header to File using MATLAB

I am reading in a .txt-file using importdata:
MC_file = importdata('D:\Simon\Dropbox\SGM\Gigerwald\Results\Multi_SGM_10000.txt');
Data = MC_file.data
Header = MC_file.colheaders
which gives me a struct-variable with the header and the data-body:
data = 10000x52 double
colheaders = 1x52 cell
Now i'd like to change the data, i.e. add some columns to the end of the file and then print the file again with the same header + 5 new columns.
The body can be printed easily using dlmwrite(), e.g. like this:
dlmwrite('SGM.txt',Data,'precision',8,'delimiter','\t','newline','pc','-append')
...but how do I print the header into the file, of which I have a array of cells? I've seen this, but since I end up with 57 columns hard-coding is not an option...
The solution is attainable using repmat. Assuming that your file is tab separated, you can use:
NUM_COLS = 57;
A=cellstr(num2str((1:NUM_COLS)'))';
fid=fopen('newfile.txt','w');
fprintf(fid,repmat('%s\t ',[1,NUM_COLS]),A{:});
fclose(fid);
The result can be previewed with:
sprintf(repmat('%s\t ',[1,NUM_COLS]),A{:})

Extract variables from a textfile in matlab

I have a large text file (~3500 lines) which contains output data from an instrument. This consists of repeated entries from different measurements which are all formatted as follows:
* LogFrame Start *
variablename1: value
variablename2: value
...
variablename35: value
* LogFrame End *
Each logframe contains 35 variables. From these I would like to extract two, 'VName' and 'EMGMARKER' and put the associated values in columns in a matlab array, (i.e. the array should be (VName,EMGMARKER) which I can then associate with data from another output file which I already have in a matlab array. I have no idea where to start with this in order to extract the variables from this file, so hence my searches on the internet so far have been unsuccessful. Any advice on this would be much appreciated.
You could use textscan:
C = textscan(file_id,'%s %f');
Then you extract the variables of interest like this:
VName_indices = strcmp(C{1},'VName:');
VName = C{2}(VName_indices);
If the variable names, so 'VName' and 'EMGMARKER' , are always the same you can just read through the file and search for lines containing them and extract data from there. I don't know what values they contain so you might have to use cells instead of arrays when extracting them.
fileID = fopen([target_path fname]); % open .txt file
% read the first line of the specified .txt file
current_line = fgetl(fileID);
counter = 1;
% go through the whole file
while(ischar(current_line))
if ~isempty(strfind(current_line, VName))
% now you find the location of the white space delimiter between name and value
d_loc = strfind(current_line,char(9));% if it's tab separated - so \t
d_loc = strfind(current_line,' ');% if it's a simple white space
variable_name{counter} = strtok(current_line);% strtok returns everything up until the first white space
variable_value{counter} = str2double(strtok(current_line(d_loc(1):end)));% returns everything form first to second white space and converts it into a double
end
% same block for EMGMARKER
counter = counter+1;
current_line = fgetl(fileID);% next line
end
You do the same for EMGMARKER and you have cells containing the data you need.