gusucode.com > datatypes 工具箱matlab源码程序 > datatypes/@timetable/lag.m
function tt = lag(tt, lagSteps) %LAG Lag or lead data in a timetable. % TT2 = LAG(TT1) shifts the data in each variable in the timetable TT1 % forward in time (a "lag") by one time step. TT must be regular. % % TT2 = LAG(TT1,DT) shifts the data by the amount of time DT. DT is a duration % or calendarDuration, and must be a multiple of TT's regular time step. % Positive values of DT shift the data forward in time (a "lag"), negative % values shift the data backwards (a "lead"). % % LAG(TT,N) shifts the data in the timetable TT1 by N timesteps. Positive % values of N shift the data forward in time (a "lag"), negative values shift % the data backwards (a "lead"). % % Examples: % % % Lag a monthly series of values, and combine with the unlagged values. % monthly = timetable(datetime(2016,1:5,3)', [1:5]') % lagged = lag(monthly,calmonths(2)) % combined = synchronize(monthly,lagged) % % % LAG shifts the data and leaves the times alone. An alternative is to % % add the lag to the time vector, and leave the data alone. % lagged = monthly % lagged.Time = lagged.Time + calmonths(2) % combined = synchronize(monthly,lagged) % % See also RETIME, SYNCHRONIZE, ISREGULAR. % Copyright 2016 The MathWorks, Inc. import matlab.internal.tableUtils.isScalarInt import matlab.internal.tableUtils.defaultarrayLike % Parse inputs if nargin == 1 % Timetable must be regular either in absolute time or with respect to a single % unit calendarDuration if ~isregularTimeDaysMonths(tt) error(message('MATLAB:timetable:lag:MustBeRegular')); end % Lag by 1x time interval: get the sign of time difference for correct lead/lag % direction with both ascending and descending times. lagSteps = sign(seconds(diff(tt.rowDim.labels(1:2)))); else % nargin==2 % LAGSTEPS must be a scalar if ~isscalar(lagSteps) error(message('MATLAB:timetable:lag:InvalidLagType')); end if isnumeric(lagSteps) % Timetable must be regular in either absolute or calendar time if ~isregularTimeDaysMonths(tt) error(message('MATLAB:timetable:lag:MustBeRegular')); end % Need the sign of the difference in the times so that lagSteps will be in % the right direction for both ascending and descending regular times. lagSteps = sign(seconds(diff(tt.rowDim.labels(1:2)))) * lagSteps; elseif isduration(lagSteps) % Timetable must be regular with respective to absolute time [tt_isregular, tt_step] = isregular(tt); if ~tt_isregular error(message('MATLAB:timetable:lag:MustBeRegularInUnits','Time')); end % Transform lagSteps into # multiples of timetable time step lagSteps = lagSteps / tt_step; elseif iscalendarduration(lagSteps) % calendarDuration lag is invalid on a duration timetable if isduration(tt.rowDim.labels) error(message('MATLAB:timetable:lag:calDurLagDurationTimetable')); end % time table interval and lag parts calUnits = {'months' 'days' 'time'}; [nMonthLag, nDayLag, timeLag] = split(lagSteps, calUnits); lagParts = [nMonthLag nDayLag seconds(timeLag)]; % Do not allow calendarDuration lagStep that is not pure % multiple of calmonths, caldays or time unit if nnz(lagParts)>1 error(message('MATLAB:timetable:lag:InvalidCaldurationLag')); end % Input timetable MUST be regular WITH RESPECT TO units in specified lag step [tt_isregular, tt_step] = isregular(tt, calUnits{lagParts~=0}); if ~tt_isregular error(message('MATLAB:timetable:lag:MustBeRegularInUnits',calUnits{lagParts~=0})); end % Extract the months, days and the time if isduration(tt_step) ttParts = [0 0 seconds(tt_step)]; else [nMonthStepTT, nDaysStepTT, timeStepTT] = split(tt_step, {'months' 'days' 'time'}); ttParts = [nMonthStepTT nDaysStepTT seconds(timeStepTT)]; end % When a timetable part equals zero, the corresponding lag part must also % equal zero; otherwise the lag cannot be multiple of timetable interval if any(lagParts(ttParts==0)~=0) error(message('MATLAB:timetable:lag:LagMustBeTimeStepMultiple')); end % Compute number of multiples each lag part is of timetable part. % Only consider components correspond to non-zero timetable parts, % as previous check guarantees the 'zero'-parts already match up. lagSteps = lagParts(ttParts~=0)./ttParts(ttParts~=0); % Lag is whole multiples of timetable interval IF_AND_ONLY_IF each % lagParts are equal multiple of corresponding timetable interval % parts; in which case lag steps equals to that number of multiple. % Otherwise, let 'steps' fall through to error in isScalarInt below lagSteps = unique(lagSteps); else error(message('MATLAB:timetable:lag:InvalidLagType')); end % Make sure lagTime is whole multiples of timetable intervals if ~isScalarInt(lagSteps) error(message('MATLAB:timetable:lag:LagMustBeTimeStepMultiple')); end end % lagSteps _IS_ whole number multiple of timetable intervals at this point. Cap % lead/lag steps by number of rows, and perform the lag/lead operation. lagSteps = sign(lagSteps) * min(abs(lagSteps),tt.rowDim.length); tt_data = tt.data; for iVar = 1:tt.varDim.length if lagSteps>=0 tt_data{iVar}(1+lagSteps:end,:) = tt_data{iVar}(1:end-lagSteps,:); tt_data{iVar}(1:lagSteps,:) = defaultarrayLike(size(tt_data{iVar}(1:lagSteps,:)), 'Like', tt_data{iVar}); else % -ve lag => lead tt_data{iVar}(1:end+lagSteps ,:) = tt_data{iVar}(1-lagSteps:end,:); tt_data{iVar}(end+lagSteps+1:end,:) = defaultarrayLike(size(tt_data{iVar}(end+lagSteps+1:end,:)), 'Like', tt_data{iVar}); end end tt.data = tt_data; end function tf = isregularTimeDaysMonths(tt) tf = isregular(tt,'Time') || isregular(tt,'Days') || isregular(tt,'Months'); end