sorting a timer in matlab - matlab

ok it seems like a simple problem, but i am having problem
I have a timer for each data set which resets improperly and as a result my timing gets mixed.
Any ideas to correct it? without losing any data.
Example
timer col ideally should be
timer , mine reads
1 3
2 4
3 5
4 6
5 1
6 2
how do i change the colum 2 or make a new colum which reads like colum 1 without changing the order of ther rows which have data
this is just a example as my file lengths are 86000 long , also i have missing timers which i do not want to miss , this imples no data for that period of time.
thanks
EDIT: I do not want to change the other columns. The coulm 1 is the gps counter and so it does not sync with the comp timer due to some other issues. I just want to change the row one such that it goes from high to low without effecting other rows. also take care of missing pts ( if i did not care for missing pts simple n=1: max would work.
missing data in this case is indicated by missing timer. for example i have 4,5,8,9 with missing 6,7
Ok let me try to edit agian
its a 8600x 80 matrix of data:
timer is one row which should go from 0 to 8600
but timer starts at odd times , so i have start of data from middle , lets say 3400, so in the middle of day my timer goes to 0 and then back to 1.
but my other rows are fine. I just need 2 plot other sets based on timer as time.
i cannot use T= 1:length(file) as then it ignores missed time stamps ( timers )
for example my data reads like
timer , mine reads
1 3
2 4
3 5
4 8
5 9
8 1
9 2
so u can see time stamps 6,7 are missing.
if i used n=1:length(file)
i would have got
1 2 3 4 5 6 7
which is wrong
i want
1 2 3 4 5 8 9
without changing the order of other rows , so i cannot use sort for the whole file.

I assume the following problem
data says
3 100
4 101
5 102
NaN 0
1 104
2 105
You want
1 100
2 101
3 102
NaN 0
4 104
5 105
I'd solve the problem like this:
%# create test data
data = [3 100
4 101
5 102
NaN 0
1 104
2 105];
%# find good rows (if missing data are indicated by zeros, use
%# goodRows = data(:,1) > 0;
goodRows = isfinite(data(:,1));
%# count good rows
nGoodRows = sum(goodRows);
%# replace the first column with sequential numbers, but only in good rows
data(goodRows,1) = 1:nGoodRows;
data =
1 100
2 101
3 102
NaN 0
4 104
5 105
EDIT 1
Maybe I understand your question this time
data says
4 101
5 102
1 104
2 105
You want
1 4 101
2 5 102
4 1 104
5 2 105
This can be achieved the following way
%# test data
data = [4 101
5 102
1 104
2 105];
%# use sort to get the correct order of the numbers and add it to the left of data
out = [sort(data(:,1)),data]
out =
1 4 101
2 5 102
4 1 104
5 2 105
EDIT 2
Note that out is the result from the solution in EDIT 1
It seems you want to plot the data so that there is no entry for missing values. One way to do this is to make a plot with dots - there won't be a dot for missing data.
plot(out(:,1),out(:,3),'.')
If you want to plot a line that is interrupted, you have to insert NaNs into out
%# create outNaN, that has NaN-rows for missing entries
outNaN = NaN(max(out(:,1)),size(out,2));
outNaN(out(:,1),:) = out;
%# plot
plot(out(:,1),out(:,3))

Related

How to filter out bad values in a data set regarding a matrix in matlab?

I wanted to ask any keen users here how to "filter out" bad values regarding a tremendous amount of a data matrix in matlab.
e.g: I have a MATLAB data file containing values 2*5000 (double) which represent x and y coordinates. How is it possible to delete all values above or under a certain limit?
or easier:
(matrix from data file)
1 2 4 134 2
3 5 5 4 2
or
1 2 4 9 2
3 5 5 234 2
setting a certain limit and delete column:
1 2 4 2
3 5 5 2
Find the "bad" elements, e.g. A < 0 | A > 20
Find the "good" columns, e.g. ~max(A < 0 | A > 20)
Keep the "good" columns / Remove the "bad" columns, e.g. A(:, ~max(A < 0 | A > 20))

How to rename values in order in matlab?

Say I have this vector A:
A=[2
92
91
91
91
92
9
92
-1
91];
I want to write a code to rename the smallest entry as 1, the next smallest entry as 2, and so on. So, I want the output to be:
B=[2
5
4
4
4
5
3
5
1
4];
How do I do that with a short and efficient code? The code I have been able to write is a "check one by one and rename" kind of code, which is highly inefficient.
U=unique(A);
for a=1:size(U,1)
for b=1:size(A,1)
if A(b,1)==U(a,1)
B(b,1)=a;
end
end
end
Is it possible to write one without using for loops, or one that is otherwise efficient?
As a consequence of unique sorting the output, your desired array is automatically built by the function and is accessible via the third output:
>> A=[2;92;91;91;91;92;9;92;-1;91];
>> [~,~,B] = unique(A)
B =
2
5
4
4
4
5
3
5
1
4

How to sort parts of table in Matlab?

I have a table in Matlab containing test data from different test persons. The test has seven video clips each with four different audio versions, which the test persons must rate on a scale from 1 to 100. Every video clip is presented twice for statistical accuracy. The test person pushes buttons 1-4 on an interface to hear the different audio versions.
My table contains the following columns (among some others that are not relevant for the question):
Test Person ID Audio Version Video Clip Rating
1 1 Forest 40
1 2 Forest 60
1 3 Forest 20
1 4 Forest 100
Now, to introduce minimal bias towards any favor of a particular button during the test, the audio versions are randomly permuted between every video clip. This means the real data will look somewhat more like this (Audio Version not sorted):
Test Person ID Audio Version Video Clip Rating
1 1 Forest 40
1 2 Forest 60
1 3 Forest 20
1 4 Forest 100
1 3 City 10
1 2 City 50
1 1 City 40
1 4 City 7
1 4 Inside 90
1 2 Inside 58
1 1 Inside 22
1 3 Inside 35
What I want to do is to: Maintain the correct order of the video clips, thus still have Forest -> City -> Inside, but have them all ordered so that is always audio version 1, 2, 3, 4:
Test Person ID Audio Version Video Clip Rating
1 1 Forest 40
1 2 Forest 60
1 3 Forest 20
1 4 Forest 100
1 1 City 40
1 2 City 50
1 3 City 10
1 4 City 7
1 1 Inside 22
1 2 Inside 58
1 3 Inside 35
1 4 Inside 90
My initial thought was to use the sortrow() function in Matlab and then sort them ascendingly along with the video clip, but since the video clips are introduced twice at different stages of the test and I want to maintain the same sequence of the clips in the table this doesn’t work. Also the same video clips are presented to numerous different test persons.
I am using a pre-made function that has to have the data sorted in this way to perform statistical calculations on it. This function takes the Matlab data from a struct and puts it into the table via a for-loop row for row.
Because the data is put into the table via a for-loop I thought there might be a way to only sort a fixed number of rows at a time i.e row 1-4, 5-8, 9-12 and so on. Do you know if there is a way to sort only part of a table in Matlab?
You can do this with a single call to sortrows by creating an additional numeric column representing your fixed pattern of video presentations. This additional column will simply label each set of 4 rows with a successive integer. It can be concatenated to the beginning of the table, then you can sort by the first and third columns to get the ordering you want:
[~, index] = sortrows([table(ceil((1:size(T, 1)).'./4)) T], [1 3]);
T = T(index, :);
And the output:
T =
ID Audio Video Rating
__ _____ ________ ______
1 1 'Forest' 40
1 2 'Forest' 60
1 3 'Forest' 20
1 4 'Forest' 100
1 1 'City' 40
1 2 'City' 50
1 3 'City' 10
1 4 'City' 7
1 1 'Inside' 22
1 2 'Inside' 58
1 3 'Inside' 35
1 4 'Inside' 90
Using reshape and sort you can do:
[~,idx]=sort(reshape(Audio_Version,4,[]));
idxtble = bsxfun(#plus,idx,0:4:(4*size(idx,2))-1);
table2 = table1(idxtble,:);
Explanation:
You can extract the audio column and reshape it to to [4 * n] matrix:
audio = reshape(Audio_Version,4,[]);
then sort columns of audio and get indexes of sorted elements:
[~,idx]=sort(audio);
Here idx represents row numbers of the sorted elements.
Convert idx to linear indexes of the whole column of the table:
idxtbl = bsxfun(#plus,idx,0:4:(4*size(idx,2))-1);
Reorder the table:
table2 = table1(idxtbl,:);
Just using sortrow for the specified part of the table like the following:
table(1:4,:) = sortrow(table(1:4,:), 2);
table(4:8,:) = sortrow(table(4:8,:), 2);
table(8:12,:) = sortrow(table(8:12,:), 2);
First sort the part of the table, then replace it with that part.

Find the increasing and decreasing trend in a curve MATLAB

a=[2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2].
Here is an array i need to extract the exact values where the increasing and decreasing trend starts.
the output for the array a will be [2(first element) 2 6 9]
a=[2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2].
^ ^ ^ ^
| | | |
Kindly help me to get the result in MATLAB for any similar type of array..
You just have to find where the sign of the difference between consecutive numbers changes.
With some common sense and the functions diff, sign and find, you get this solution:
a = [2 3 6 7 2 1 0.01 6 8 10 12 15 18 9 6 5 4 2];
sda = sign(diff(a));
idx = [1 find(sda(1:end-1)~=sda(2:end))+2 ];
result = a(idx);
EDIT:
The sign function messes things up when there are two consecutive numbers which are the same, because sign(0) = 0, which is falsely identified as a trend change. You'd have to filter these out. You can do this by first removing the consecutive duplicates from the original data. Since you only want the values where the trend change starts, and not the position where it actually starts, this is easiest:
a(diff(a)==0) = [];
This is a great place to use the diff function.
Your first step will be to do the following:
B = [0 diff(a)]
The reason we add the 0 there is to keep the matrix the same length because of the way the diff function works. It will start with the first element in the matrix and then report the difference between that and the next element. There's no leading element before the first one so is just truncates the matrix by one element. We add a zero because there is no change there as it's the starting element.
If you look at the results in B now it is quite obvious where the inflection points are (where you go from positive to negative numbers).
To pull this out programatically there are a number of things you can do. I tend to use a little multiplication and the find command.
Result = find(B(1:end-1).*B(2:end)<0)
This will return the index where you are on the cusp of the inflection. In this case it will be:
ans =
4 7 13

Dividing selected elements of array on Matlab

I have the following array
a = [ 1 10 3 4 68 2 34 8 10 ]
And I need to divide each number (/2) if this number is higher than 9.
This means that 1 has not to be divided, and 10 has to be divided (/2)
The resulting array should be:
a = [ 1 5 3 4 34 2 17 8 5 ]
I have to do it without using a FOR function. So I tried with this:
a = a./2;
This divides every number of the array, and I as told you before, I want to divide only the ones higher than 9.
Can anyone tell me how can I do it? Add a 'if whatever>5' in that statement or something?
Thanks in advance
Use logical indexing for both dividing only the numbers that meets your criterion and for assigning the result to those specific indices.
a = [ 1 10 3 4 68 2 34 8 10 ];
a(a>9) = a(a>9) ./ 2