How do I reshape 3 vectors (date, depth, and variables) into a matrix separated by day?
Show older comments
This is my first question, and I’m struggling for an eloquent way to do this. I have a large dataset of vectors separated by parameter, and I would like to reshape into a matrix in order to do 3D Matlab manipulations. For example, I get an error if I try to use pcolor with 3 vectors. I’ve attached a data sample.
I’d like to end up with a matrix where X = Datetime (separated by day), Y = water depth, and Z = variable (such as water temperature, salinity, etc.).
Here is a snapshot of the existing data format, where size of each vector = 7 x 1:
SampleDate = [01/28/2014 12:13:37; 01/28/2014 12:14:58; 01/28/2014 12:15:20; 02/06/2014 11:02:42; 02/06/2014 11:05:59; 02/06/2014 11:06:24; 02/06/2014 11:06:32];
Depth = [1.5; 5; 10; 1; 5; 10; 12];
SampleTemperature = [8.22; 8.29; 8.29; 7.72; 7.88; 7.9; 7.92];
I would like to transform to a matrix, so that I end up with instead a size of 4 x 2. For example,
SampleDate = 01/28/2014 12:13:37 02/06/2014 11:02:42
01/28/2014 12:14:58 02/06/2014 11:05:59
01/28/2014 12:15:20 02/06/2014 11:06:24
NaN 02/06/2014 11:06:32
SampleTemperature = 8.22 7.72
8.29 7.88
8.29 7.9
NaN 7.92
I recognize that I will have to have NaN values if some of the vectors are shorter than others, and the length of the matrix will be equal to the max of the number of samples per day, so I put this in the example.
I will be filtering the data first so that I use only the value of “Down” for the down cast results. Below is the import code that I have currently to load the attached file.
[file, pathname] = uigetfile({'*.*', 'All Files (*.*)'}, 'Load the CTD profile xls file');
fid = fopen(file);
headerline = fgetl(fid);
formatSpec = '%s%s%f%s%s%f%s%f%s%f%s%f%s%f%s%f%s%f%s%f%s%f%s%s%s';
data = textscan(fid,formatSpec,'Delimiter','\t');
fclose(fid);
%Pull out the row with the headers
headers = textscan(headerline,'%s','Delimiter','\t');
%Remove special characters from the header text
headers{1,1} = regexprep(headers{1,1},'[%!/()^, =]','');
%Convert 1st column into the date time format
data{2} = datetime(data{2}, 'Format', 'MM/dd/yyyy HH:mm:ss', 'InputFormat', 'M/d/yyyy h:mm:ss a');
%Create a structure array
datastr = struct();
for i=1:numel(headers{:})
datastr.(headers{1}{i}) = data{i};
end
%Next, index so looking at the down cast only
idxD = ~cellfun('isempty',strfind(datastr.Updown,'Down'));
%Pull out vectors of interest
SampleDate = datastr.Sampledate(idxD);
Depth = datastr.Depth(idxD);
SampleTemperature = datastr.SampleTemperatureFielddegC(idxD);
clear ans fid file formatSpec headerline k n tline i pathname data headers;
2 Comments
Jan
on 26 Dec 2016
I do not understand the question. What is "a matrix separated by day" and a "vectors separated by parameter"?
StephanieJ
on 3 Jan 2017
Accepted Answer
More Answers (1)
Peter Perkins
on 27 Dec 2016
I'm not sure I've understood exactly what you need to do, but this seems related:
Create a table containing data like yours:
>> Date = datetime({'01/28/2014 12:13:37'; '01/28/2014 12:14:58'; '01/28/2014 12:15:20'; '02/06/2014 11:02:42'; '02/06/2014 11:05:59'; '02/06/2014 11:06:24'; '02/06/2014 11:06:32'});
>> Depth = [1.5; 5; 10; 1; 5; 10; 12];
>> Temperature = [8.22; 8.29; 8.29; 7.72; 7.88; 7.9; 7.92];
Add some variables that will help transform the data:
>> ID = [1;2;3;1;2;3;4];
>> Day = dateshift(Date,'start','day');
>> Day = categorical(Day,datetime({'01/28/2014' '02/06/2014'}),{'First' 'Second'});
>> t = table(ID,Day,Date,Depth,Temperature)
t =
ID Day Date Depth Temperature
__ ______ ____________________ _____ ___________
1 First 28-Jan-2014 12:13:37 1.5 8.22
2 First 28-Jan-2014 12:14:58 5 8.29
3 First 28-Jan-2014 12:15:20 10 8.29
1 Second 06-Feb-2014 11:02:42 1 7.72
2 Second 06-Feb-2014 11:05:59 5 7.88
3 Second 06-Feb-2014 11:06:24 10 7.9
4 Second 06-Feb-2014 11:06:32 12 7.92
Unstack the "stacked" data to an "unstacked" format:
>> t = unstack(t,{'Date' 'Depth' 'Temperature'},'Day','GroupingVariable','ID')
t =
4×7 table
ID Date_First Date_Second Depth_First Depth_Second Temperature_First Temperature_Second
__ ____________________ ____________________ ___________ ____________ _________________ __________________
1 28-Jan-2014 12:13:37 06-Feb-2014 11:02:42 1.5 1 8.22 7.72
2 28-Jan-2014 12:14:58 06-Feb-2014 11:05:59 5 5 8.29 7.88
3 28-Jan-2014 12:15:20 06-Feb-2014 11:06:24 10 10 8.29 7.9
4 NaT 06-Feb-2014 11:06:32 NaN 12 NaN 7.92
Now you can access the paired variables using braces and get back one matirx for each pair:
>> t{:,{'Date_First' 'Date_Second'}}
ans =
4×2 datetime array
28-Jan-2014 12:13:37 06-Feb-2014 11:02:42
28-Jan-2014 12:14:58 06-Feb-2014 11:05:59
28-Jan-2014 12:15:20 06-Feb-2014 11:06:24
NaT 06-Feb-2014 11:06:32
>> t{:,{'Temperature_First' 'Temperature_Second'}}
ans =
8.22 7.72
8.29 7.88
8.29 7.9
NaN 7.92
1 Comment
StephanieJ
on 3 Jan 2017
Categories
Find more on Data Preprocessing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!