How do I get a function in a for loop so it applies it to an entire table?
1 次查看(过去 30 天)
显示 更早的评论
My code:
t = timetable2table(tt);
t2=t(:,1:2); % here it takes only one station out of a table
t2.Year= dateshift(t.Date,'start','year'); % Here I create a seperate date column, which takes out the time from the date column
rowfun(@myFun,t2,'GroupingVariable','Year','OutputVariableNames',{'Max' 'MaxX'}) % Here it finds the maximum of each year (of one station) and the time the maximum occurred
function [tmax,xmax] = myFun(t,x)
[xmax,imax] = max(x,[],1);
tmax = t(imax);
end
How do I get this to loop for each station so it finds the maximum for each year for each station and the time the maximum occurred?
5 个评论
Cris LaPierre
2021-3-12
编辑:Cris LaPierre
2021-3-12
You don't want rowfun. Rowfun assumes each column of your table is an input to your function, and is applied to each row separately. You kind of want the exact opposite, meaning you want it to look at all rows, and apply to each column separately.
While groupsummary can help you find the yearly max for each station without a loop, to get the corresponding timestamp for each station likely will.
Since it's much easier to test with actual data, consider sharing your table. Save it to a mat file and attach it to your post using the paperclip icon.
采纳的回答
Cris LaPierre
2021-3-12
编辑:Cris LaPierre
2021-3-12
To follow up, the easiest way to find yearly max is to use groupsummary with the appropriate settings.
load matlabworkspace28.02.mat
yrMax = groupsummary(tt,"Kuupev","year","max",'IncludeMissingGroups',false)
However, this will not give you the corresponding timestamp for each max. There is no slick way I could think of to do that, so here's my brute force attempt.
% Find the years in the timetable
Y = min(year(tt.Kuupev)):max(year(tt.Kuupev));
% create a new table to hold the results
yrTbl = array2table(NaT(length(Y),2*width(tt)),"VariableNames",["Date" "Station"]' + (1:width(tt)));
yrTbl = convertvars(yrTbl,2:2:width(yrTbl),@datenum);
% loop through each year
for y = 1:length(Y)
% find the max value for each station plus the corresponding index
dateInd = find(year(tt.Kuupev)==Y(y));
[val,ind] = max(tt{dateInd,:});
% Assign values to output table
C = 1:2:width(yrTbl);
yrTbl{y,C} = tt.Kuupev(dateInd(ind))';
yrTbl{y,C+1} = val;
% If max is NaN, set time to NaT
yrTbl{y,C(isnan(val))} = NaT;
end
% View results
yrTbl
2 个评论
Cris LaPierre
2021-3-12
You should inspect the data for that year at that station. You might find the answer makes sense.
更多回答(3 个)
Prudhvi Peddagoni
2021-3-12
编辑:Prudhvi Peddagoni
2021-3-12
Hi,
First, run a for loop over all the rows of data to take note of the indices of each year. For more info about table indexing, refer this
indices = zeros(1,9); % stores starting indices of years
currentYear = 2011;
for idx = 1:length(t)
if year(t.Date(idx)) == currentYear
currentYear = currentYear+1;
indices(currentYear-2011) = idx;
end
end
After this, use a for loop to go over each year. For each year, extract the rows of that year from the table to a matrix. Then give that matrix to the max function like this:
[maxValues, correspondingIndices] = max(matrix,[],2);
After getting the indices, you can get the corresponding date from the table.
Hope this helps.
0 个评论
Allen
2021-3-12
编辑:Allen
2021-3-12
A relatively general approach to extract max values by year for each table variable (stations in this case) assuming the first variable of the table is a datetime value.
t = timetable2table(tt);
Vars = t.Properties.VariableNames; % Extract Variable Names
Yrs = unique(year(t.(Vars{1}))); % Get unique year values, using t.(Vars{1}) instead of t.Date since data provided had non-English labels.
Yrs(isnan(Yrs)) = []; % Remove NaN values
% Loop for each year and find max value for all stations
xmax = zeros([length(Yrs),length(Vars)-1]); % Pre-allocate for speed
for i=1:length(Yrs)
xmax(i,:) = max(t{year(t.(Vars{1}))==Y(i),2:end});
end
% Convert results to table
tmax = array2table([Yrs,xmax],'VariableNames',Vars);
Seth Furman
2021-3-22
To add to Chris' answer, you can also find the yearly max for each station using retime. For example, using the first two columns of the timetable you provided
>> load matlabworkspace28.02.mat
>> ttMax = retime(tt(:,1:2),'yearly','max')
ttMax =
9×2 timetable
Kuupev AJHAAP01 AJHARK01
___________ ________ ________
01-Jan-2011 11.3 15.8
01-Jan-2012 31.3 13.7
01-Jan-2013 44.8 18.5
01-Jan-2014 16.6 12
01-Jan-2015 9.2 10
01-Jan-2016 11.6 21
01-Jan-2017 10.3 23.8
01-Jan-2018 16 15.7
01-Jan-2019 14 13.1
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Dates and Time 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!