How to split data into two matrices

I am doing some analysis for my Honor's Thesis and am having some problems pre-processing of the data. The data is in a 4x147000 matrix. Row one is the time, two and three are my signals of interest, and the fourth is the stimulus - the condition I want to split the data up by. Due to imperfect data, not all of the events are the same length, so I need to take chunks of data either 490 or 990 columns long depending on the value of the fourth row. For example, I want to take the first 490 columns whose fourth row equals 0 and put into a new matrix "datanostim." Then I want to scan the matrix until the fourth row changes to 255, and take the first 990 columns whose fourth row equals 255 and add to a new matrix "datastim." This then repeats, so the next 490 columns whose fourth row is 0 is added to the datanostim matrix, the next 990 columns whose fourth row is 255 added to the datastim matrix, and so on.
Here is my attempt, but I would love to see other methods as well, as mine gives me the following: "Error: Function definitions are not permitted in this context."
function [datastim, datanostim] = datacutoff(data, stim, nostim)
%UNTITLED Summary of this function goes here
% data = data as matrix, fourth row as stim 0 or 255
% stim = length of stimulus
% nostim = length without stimulus
datastim = [];
datanostim = [];
i = 1;
if data(4,i) ~= data(4,i+1)
i = i+1;
else if data(4,i:i+nostim) == 0
horzcat (data(:,i:i+nostim), datanostim);
i = i+nostim;
end
end
if data(4,i) ~= data (4,i+1)
i = i+1;
else if data(4,i:i+stim) == 255
horzcat (data(:,i:i+stim), datastim);
i = i+stim;
end
end
end
Thanks!

 Accepted Answer

"Error: Function definitions are not permitted in this context."
To solve that, you need to save your ‘datacutoff’ function to a separate .m-file ‘datacutoff.m’ in your MATLAB search path. Then you should be able to use it.
Then run it.

10 Comments

datacutoff.m is an individual file in a folder of general code that is set as a path for Matlab. Do I need to add a save line to the code itself? I don't have too much experience in Matlab, so I could see that I am merely misunderstanding your comment.
Thanks,
If you don’t have a function definition such as ‘datacutoff’ in your script file, I don’t see how you could be getting that error.
How are you calling it in your main script? You should be calling it as:
[datastim, datanostim] = datacutoff(data, stim, nostim);
Oh, I see what you mean. I was referring to it incorrectly. Thanks
Now the code is just returning empty matrices for datastim and datanostim.
Apologise for the late reply. A section of your data would help to verify this, but I believe I see part of the problem.
See if this works:
Row4 = reshape(repmat([0 255], 10, 3), 1, []); % Create Data
data = [randi(10, 3, 60); Row4]; % Create Data
chg = diff([1 data(4,:)]); % Vector Of Changes From [0 255 0 255]
stimidx = find(chg > 0); % Start Of ‘255’ Segments
nstmidx = find(chg < 0); % Start Of ‘0’ Segments
stimrng = 6;
nstmrng = 7;
datastim = [];
datanostim = [];
for k1 = 1:length(stimidx)
datastim = [datastim data(:,stimidx(k1):stimidx(k1)+stimrng+1)];
end
for k1 = 1:length(nstmidx)
datanostim = [datanostim data(:,nstmidx(k1):stimidx(k1)+nstmrng+1)];
end
It seems to work as you want it to work with my test code, but I will leave it to you to make that determination. My ‘stimrng’ and ‘nstmrng’ variables are the lengths of the segments you will want to save, I believe 990 and 490 respectively. I kept them in the ranges of my simulated data to be sure they worked.
Thanks a lot Star Strider this got the program a lot further. Here is the current code, I had to add some code to stop the loops after the 98 index. However, the cutdatanostim is still empty...
I also attached a sample data set.
function [ datastim, datanostim ] = datacutoff2( data, stimlen, nostimlen )
% data = 4 rows: time, electrode1, electrode2, and stimulus
% stimlen = the length of the stimulus trial
% nostimlen = the length of trial without stimulus
chg = diff([1 data(4,:)]); %Creates a vector of changes from 0 to 255 to 0
stimind = find(chg > 0); %Start index of 255 data
nostimind = find(chg < 0); %Start index of 0 data
datastim = []; %Forms empty matrix for stimulation data
datanostim = []; %Forms empty matrrix for no stimulation data
for k1 = 1:length(stimind)
datastim = [datastim data(:,stimind(k1):stimind(k1)+stimlen+1)];
end
if stimind == [1:98]
for k1 = 1:length(nostimind)
datanostim = [datanostim data(:,nostimind(k1):stimind(k1)+nostimlen+1)];
end
else end
If you only want the first 98 indices (I didn’t know that), the loops in my code with your range variables become:
for k1 = 1:length(stimidx(1:98))
datastim = [datastim data(:,stimidx(k1):stimidx(k1)+stimlen+1)];
end
for k1 = 1:length(nstmidx(1:98))
datanostim = [datanostim data(:,nstmidx(k1):stimidx(k1)+nostimlen+1)];
end
The if block is not necessary. (You could also simply limit them to 1:98, but I kept the variable names in the for statements to help me follow it, and to make sure we’re talking about the same things.)
I don’t understand about ‘cutdatanostim’. It’s not in your original function that I can see, and you’re not returning it as an output of your function. Does it figure in the function at all? What is it and what do you want to do with it?
Sorry about that, I didn't know it either until I ran it with the data. After 98 trials it runs out of data and causes an error. That is why I put that in. The 'cutdatanostim' was a typo on my part. It looks like it is working!
Thanks a lot, I need to work on my indexing.
My pleasure!
This was a fun project for me.
I'm glad because there is slight problem. When I run it at lengths of 490 for nostim and 990 for stim, the trial lengths aren't consistent. For example, the datanostim out put is a 4X48216, which means that out of 98 trials each is 492 bins. The problem also occurs for the datastim.
Delete the +1 at the end of the ‘datastim’ and ‘nodatastim’ assignments in the loops. If you’re still having problems, convert them to -1. (It wasn’t clear to me where you were counting from.)
Also, I just picked up a typo I didn’t see before. Change the ‘datanostim’ assignment to:
datanostim = [datanostim data(:,nostimind(k1):nostimind(k1)+nostimlen+1)];
changing the +1 as appropriate to get the addressing correct.
To avoid the problem with the index ranges exceeding the ‘data’ column size, you could put as the first statements in both for loops:
if (stimind(k1)+stimlen > length(data,2))
return
end
and:
if (nostimind(k1)+nostimlen > length(data,2))
return
end
respectively, and include the appropriate +1 or other indexing corrections there as well. That will test to be sure you’re not over-reading ‘data’, and if either one is true it will immediately return to the calling script rather than throwing the error. The ‘1:98’ limitation will not be necessary with these if blocks. If you’re happy with the ‘1:98’ limitation, keep them as they are now.

Sign in to comment.

More Answers (1)

Categories

Asked:

on 3 Nov 2014

Edited:

on 7 Nov 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!