Append data or values to csv file Column wise in matlab - matlab

suppose i have a .csv file And it has the values as follows:
A 23 45
B 69 84
C 48 78
D 12 34
so it has two columns. Now what i need to do is to add values staring from the 3rd column with out deleting the values in the 1st and 2nd columns..
i tried z code
fileID = fopen('exp.csv','A');
fprintf(fileID,' %12.4f\n',D);
fclose(fileID);
But the issue is that this is added all in one column like:
23
69
48
12
......
45
84
75
38
How can i do this...??

Use the csvread / csvwrite functions to load in the existing file, append a column, and write the new data.
data = csvread('exp.csv');
toadd = (1:4)';
newdata = [data toadd];
csvwrite('out.csv', newdata);

Related

How to match and copy time-data from one matrix to another?

In MATLAB (R2015a), I have two large matrices that can be simplified as:
A = [ 24 10 830; 24 15 830; 150 17 945; 231 40 1130; 231 45 1130]
(note that in A, column 3 is the time for the event cataloged in column 1) and
B = [24 13; 150 29; 231 43]
How can I match and copy the time-data from column 3 in matrix A, to a matching and filtered event column in matrix B?
For example, I want the value 24 from first column in B to be matched with value 24 from first column in A, and then copy the corresponding time-data in A's third column (for 24 it's 830, for 150 it's 945 etc.) into B. This should result into our new B with the time-data from A:
B = [24 13 830; 150 29 945; 231 43 1130]
I relatively new to MATLAB so any help is much appreciated!
First find the location of the elements in the first row of B in the first row of A using the ismember function. And then use those locations to construct the new matrix.
[~,Locb] = ismember(B(:,1),A(:,1));
Bnew = [B A(Locb,3)]
Bnew =
24 13 830
150 29 945
231 43 1130
This is a fast way that comes to my mind. There might be some singularities that needed to be checked more thoroughly.

Adding rows/ columns to existing matrix

I have the following matrix:
a = [16 456 22 85 93;11 78 310 62 36;1 66 23 67 405];
If I wanted to add a row would it be a = [a; randi(99, 1, 5)];?
And what if I also want to add a column would it be a = [a, randi(99, 4, 1)];?
How would I add specifically between the first/second row or first/second column?
a = [16 456 22 85 93;11 78 310 62 36;1 66 23 67 405]; is a 3-by-5 matrix. So if you want to add a row you need to add a 5-digit row, i.e. a = [a; randi(99, 1, 5)]; is correct. For a column it'd be a = [a, randi(99, 3, 1)];, where I replaced your 4 with a 3 to make it act on the initial matrix. Better though would be to implicitly use sizes, so that you don't have to manually increase the number of rows/columns each time:
a = [a; randi(99,1,size(a,2))]; %// adding a row
a = [a, randi(99,size(a,1),1)]; %// adding a column
If you want to insert your new row between the first and second rows:
a = [a(1,:); randi(99,1,size(a,2)); a(2:end,:)];
Consider
a = [16 456 22 85 93;11 78 310 62 36;1 66 23 67 405];
To enter before ith row:
a = [ a(1:i-1,:) ; randi(99,1,5) ; a(i:end,:) ];
To enter before ith column:
a = [ a(:,1:i-1) , randi(99,4,1) , a(:,i:end) ];

Converting a char array to string using MATLAB

date time machine power energy heat
? ? ? MW kJ kJ
2/15/2016 20:50:46 kuka 45 22 22
2/15/2016 20:50:47 kuka 50 24 22
2/15/2016 20:50:48 kuka 56 26 22
2/15/2016 20:50:49 kuka 58 28 22
2/15/2016 20:50:50 kuka 62 30 22
2/15/2016 20:50:51 kuka 60 32 22
2/15/2016 20:50:52 kuka 64 34 20
I have a textfile and I imported data using importdata() command in matlab
I have tried Delimiter with space ' ' and '\t'
All data is saved in a struct as fine I as need but the problem is in the first line all of it is saved in one cell like date time machine power energy heat
All of the other data like ? , MW , KJ and 45 are save in separate cells which are fine.
I want data from the first row as separate entities like data time machine etc
If I save that cell in a variable name X then output is like 'date time machine power energy heat'
When I check class of this its char
What I want know is to convert this char to a string so that I can continue writing code for my GUI
Answering after your comment
d = X{1}
Take any variable like Z use textscan to get your desired result
Z = textscan(d , '%s');
This will make Z a cell of order (1 X 1)
Z{1}(1) will be date
Z{1}(2) will be time
Z{1}(3) will be machine
......

Concatenation of Matlab strings

I want to make a Matlab function that takes two matrices A and B (of the same size) and combines them in a certain way to give an output that can be used in Latex - table.
I want the first row of the output matrix to consist of the first row of matrix A, with ampersands (&) in between them, and that ends with an double backslash.
The second row should be the first row of B with parentheses around them, and ampersands in between. And so on for the rest of A and B.
If I let A=rand(1,2), I could do this by using [num2str(A(1)), ' & ', num2str(A(2)),' \\'] and so on.
But I want to be able to make a function that does this for any size of the matrix A. I guess I have to make cell structures in some way. But how?
This could be one approach -
%// First off, make the "mixed" matrix of A and B
AB = zeros(size(A,1)*2,size(A,2));
AB(1:2:end) = A;
AB(2:2:end) = B;
%// Convert all numbers of AB to characters with ampersands separating them
AB_amp_backslash = num2str(AB,'%1d & ');
%// Remove the ending ampersands
AB_amp_backslash(:,end-1:end) = [];
%// Append the string ` \\` and make a cell array for the final output
ABcat_char = strcat(AB_amp_backslash,' \\');
ABcat_cell = cellstr(ABcat_char)
Sample run -
A =
183 163 116 50
161 77 107 91
150 124 56 46
B =
161 108 198 4
198 18 14 137
6 161 188 157
ABcat_cell =
'183 & 163 & 116 & 50 \\'
'161 & 108 & 198 & 4 \\'
'161 & 77 & 107 & 91 \\'
'198 & 18 & 14 & 137 \\'
'150 & 124 & 56 & 46 \\'
' 6 & 161 & 188 & 157 \\'
You can use sprintf, it will repeat the format spec as many times as required until all input variables are processed:
%combine both to one matrix
C=nan(size(A).*[2,1]);
C(1:2:end)=A;
C(2:2:end)=B;
%print
sprintf('%f & %f \\\\\n',C.')
The transpose (.') is required to fix the ordering.

How do I select n elements of a sequence in windows of m ? (matlab)

Quick MATLAB question.
What would be the best/most efficient way to select a certain number of elements, 'n' in windows of 'm'. In other words, I want to select the first 50 elements of a sequence, then elements 10-60, then elements 20-70 ect.
Right now, my sequence is in vector format(but this can easily be changed).
EDIT:
The sequences that I am dealing with are too long to be stored in my RAM. I need to be able to create the windows, and then call upon the window that I want to analyze/preform another command on.
Do you have enough RAM to store a 50-by-nWindow array in memory? In that case, you can generate your windows in one go, and then apply your processing on each column
%# idxMatrix has 1:50 in first col, 11:60 in second col etc
idxMatrix = bsxfun(#plus,(1:50)',0:10:length(yourVector)-50); %'#
%# reshapedData is a 50-by-numberOfWindows array
reshapedData = yourVector(idxMatrix);
%# now you can do processing on each column, e.g.
maximumOfEachWindow = max(reshapedData,[],1);
To complement Kerrek's answer: if you want to do it in a loop, you can use something like
n = 50
m = 10;
for i=1:m:length(v)
w = v(i:i+n);
% Do something with w
end
There's a slight issue with the description of your problem. You say that you want "to select the first 50 elements of a sequence, then elements 10-60..."; however, this would translate to selecting elements:
1-50
10-60
20-70
etc.
That first sequence should be 0-10 to fit the pattern which of course in MATLAB would not make sense since arrays use one-indexing. To address this, the algorithm below uses a variable called startIndex to indicate which element to start the sequence sampling from.
You could accomplish this in a vectorized way by constructing an index array. Create a vector consisting of the starting indices of each sequence. For reuse sake, I put the length of the sequence, the step size between sequence starts, and the start of the last sequence as variables. In the example you describe, the length of the sequence should be 50, the step size should be 10 and the start of the last sequence depends on the size of the input data and your needs.
>> startIndex = 10;
>> sequenceSize = 5;
>> finalSequenceStart = 20;
Create some sample data:
>> sampleData = randi(100, 1, 28)
sampleData =
Columns 1 through 18
8 53 10 82 82 73 15 66 52 98 65 81 46 44 83 9 14 18
Columns 19 through 28
40 84 81 7 40 53 42 66 63 30
Create a vector of the start indices of the sequences:
>> sequenceStart = startIndex:sequenceSize:finalSequenceStart
sequenceStart =
10 15 20
Create an array of indices to index into the data array:
>> index = cumsum(ones(sequenceSize, length(sequenceStart)))
index =
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
>> index = index + repmat(sequenceStart, sequenceSize, 1) - 1
index =
10 15 20
11 16 21
12 17 22
13 18 23
14 19 24
Finally, use this index array to reference the data array:
>> sampleData(index)
ans =
98 83 84
65 9 81
81 14 7
46 18 40
44 40 53
Use (start : step : end) indexing: v(1:1:50), v(10:1:60), etc. If the step is 1, you can omit it: v(1:50).
Consider the following vectorized code:
x = 1:100; %# an example sequence of numbers
nwind = 50; %# window size
noverlap = 40; %# number of overlapping elements
nx = length(x); %# length of sequence
ncol = fix((nx-noverlap)/(nwind-noverlap)); %# number of sliding windows
colindex = 1 + (0:(ncol-1))*(nwind-noverlap); %# starting index of each
%# indices to put sequence into columns with the proper offset
idx = bsxfun(#plus, (1:nwind)', colindex)-1; %'
%# apply the indices on the sequence
slidingWindows = x(idx)
The result (truncated for brevity):
slidingWindows =
1 11 21 31 41 51
2 12 22 32 42 52
3 13 23 33 43 53
...
48 58 68 78 88 98
49 59 69 79 89 99
50 60 70 80 90 100
In fact, the code was adapted from the now deprecated SPECGRAM function from the Signal Processing Toolbox (just do edit specgram.m to see the code).
I omitted parts that zero-pad the sequence in case the sliding windows do not evenly divide the entire sequence (for example x=1:105), but you can easily add them again if you need that functionality...