how to simulate date for one year in kdb - kdb

i would like to simulate random timestamp data.
100 records in a day for one year.
How am I am able to do that?
when i set a:2013.01.01D00:00:00.000000000
100?a
the randomize data doesn't stay in a day.
thanks for your input

I am not sure, if this can be done easily. But you may generate 100 random timestamps for every day of 2013 in the next way
daysInYear: 365;
year: 2013.01.01D00:00:00.000000000;
//array of 365 elements, where every element represents corresponding date of year
dates: year + 01D * til daysInYear;
//array of 365 elements, where every element is an array of 100 random timestamps [0 .. 1D)
randomNanos: cut[100; (100 * daysInYear)?1D];
//array of 365 elements, where each element is an array of 100 random dateTimes for given day
result: dates + randomNanos;
//put all the dates in single array
raze result
The short version which does the same is below:
raze (2013.01.01D+01D * til 365) + cut[100; (100*365)?1D]

In order to simulate data for a single day, it's possible to generate random times (as floats less than one) and add them to the day you would like to generate data for. In this case:
D:2016.03.01;
D+100?1f
Will return 100 random times on 2016.03.01. If you want to generate data within a time range you can restrict the size of the float to something less than 1, or greater than a certain minimum value.

If you want to handle leap years... Not sure of a better way at the minute other than adding the max number of days onto the start of the year and asking whether it's the 31st. Adding on 366, it can either be 31st or 1st. If it's the 31st good, otherwise drop off the last date.
/e.g.
q)last 2015.01.01+til 365
2015.12.31
q)last 2016.01.01+til 365
2016.12.30 /we are a day short
q)
/return the dates and the number of days based on whether its a leap year
q)dd:$[31i~`dd$last d:2016.01.01+til 366;(366;d);(365;-1_d)]
q)/returns (366;2016.01.01 2016.01.02...)
q)/the actual logic below is pretty much the same as the other answer
q)raze{[n;dy;dt] dt+n cut(n*dy)?.z.N}[100;].dd
2016.01.01D16:06:53.957527121 2016.01.01D10:55:10.892935198 2016.01.01D15:36:..

Related

Repeat date sequence in Excel

I would like to ask how to create the sequence formula in order to repeate a date 10 times and do it for the whole year.
For example starting from 01/01/2022 to copy this date 10x then for 02/01/2022 to copy it 10x and so on. I started to use following formula for sequence:
=DATE(SEQUENCE(10,1,Year(B1),Month(B1),day(B1))
where B1 is 01/01/2022 and day and month are copied 10 times but the year is changing. Is there a way to do it to have the year same as well?
Thanks in advance.
You can take advantage of the fact that a date in excel is, conveniently, an integer number, and do it like that:
=INT((ROW(B1)-1)/10) + $B$1
That'll repeat the date entered in B1 10 times and than switch to next day, using the row number as a guide (so if you are not on the first row, you may need to add + X to the formula, where x is the row offset).
(Actual raw integer shown in D column for illustration, repeating every 3 rows instead of 10 to keep the screenshot smaller)

How can I partition data based on date column to get subsets of max 1 year (365 consecutive days)

I'm quite new to R, so I still struggle a bit with what may be some of the basics. I have movement data for several individuals, and some of them have been monitored for over a year. In these cases, I'm trying to partition the data into bins of max. one year (i.e. 365 consecutive days) per individual. For example, if one individual was tracked for 800 days, I would need to partition the data into the first 365 days, the second 365 days, and the remaining 70 days. Or, if one individual started on 2019/04/17, I'd like to subset the data until 2020/04/16, with the next subset beginning on 2020/04/17.
Individuals were added in different moments so not all monitoring periods begin on the same day, and per individual there can be more than one observation per day, so many rows share the same date. Naturally I want to use the timestamp column for this, but have been looking for ways and can't seem to find one. Is there a way to tell R to pick the first date and extract the next 365 days?
I could manually calculate each bin and try to partition it by hand, but I was wondering if there was a simpler way for this. I can however separate the data per individual.
Thanks!
My data looks something like this
Date.and.time Ind Lat Long
2019-04-02 08:54:03 Animal_1 Y X
2019-04-02 09:01:13 Animal_2 Y X
2019-04-02 15:45:22 Animal_1 Y X
2019-04-03 17:31:50 Animal_1 Y X
.
.
.
2021-10-14 12:34:56 Animal_1 Y X
2021-10-15 16:05:50 Animal_20 Y X
2021-10-15 22:29:37 Animal_15 Y X

How to get monthly totals from linearly interpolated data

I am working with a data set of 10,000s of variables which have been repeatedly measured since the 1980s. The first meassurements for each variable are not on the same date and the variables are irregularly measured - sometimes measurements are only a month apart, in a small number of cases they are decades apart.
I want to get the change in each variable per month.
So far I have a cell of dates of measurements,and interpolated rates of change between measurements (each cell represents a single variable in either, and I've only posted the first 5 cells in each array)
DateNumss= {[736614;736641;736669] [736636;736666] 736672 [736631;736659;736685] 736686}
LinearInterpss={[17.7777777777778;20.7142857142857;0] [0.200000000000000;0] 0 [2.57142857142857;2.80769230769231;0]}
How do I get monthly sums of the interpolated change in variable?
i.e.
If the first measurement for a variable is made on the January 1st, and the linearly interpolated change between that an the next measurement is 1 per day; and the next measurement is on Febuary the 5th and the corresponding linearly interpolated change is 2; then January has a total change of 1*31 (31 days at 1) and febuary has a total change of 1*5+2*23 (5 days at 1, 23 days at 2).
You would need the points in the serial dates that correspond with the change of a month.
mat(:,1)=sort(repmat(1980:1989,[1,12]));
mat(:,2)=repmat(1:12,[1,size(mat,1)/12]);
mat(:,3)=1;
monthseps=datenum(mat);
This gives you a list of all 120 changes of months in the eighties.
Now you want, for each month, the change per day, and sum it. If you take the original data it is easier, since you can just interpolate each day's value using matlab. If you only have the "LinearInterpss" you need to map it on the days using interp1 with the method 'previous'.
for ct = 2:length(monthseps)
days = monthseps(ct-1):(monthseps(ct)-1); %days in the month
%now we need each day assigned a certain change. This value depends on your "LinearInterpss". interp1 with method 'previous' searches LineairInterpss for the last value.
vals = interp1(DateNumss,LinearInterpss,days,'previous');
sum(vals); %the sum over the change in each day is the total change in a month
end

MATLAB: Find all values on one date, then filter down to an hour and find average [duplicate]

This question already has answers here:
Counting values by day/hour with timeseries in MATLAB
(3 answers)
Closed 6 years ago.
I have a year's worth of data, the data is recorded one minute intervals each day of the year.
The date and time was imported from excel (in form 243.981944, then by adding 42004 (so will be for 2015) and formatting to date it becomes 31.8.15 23:34:00).
Importing to MATLAB it becomes
'31/08/2015 23:34:00'
I require the data for each day of the year to be at hourly intervals, so I need to sum the data recorded in each hour and divide that by the number of data recorded for that hour, giving me the hourly average.
For some reason the data in August actually increments in 2 minute intervals, data for every other month increments in one minute intervals.
ie
...
31/07/2015 23:57:00
31/07/2015 23:58:00
31/07/2015 23:59:00
31/08/2015 00:00:00
31/08/2015 00:02:00
31/08/2015 00:04:00
...
I'm not sure how I can find all the values for a specific date and hour in order to work out the averages. I was thinking of using a for loop to find the values on each day, but when I got down to writing code realised this wouldn't work the way I was thinking.
I presume there must be some kind of functions available that would allow for data to be filtered by the date and time?
edit:
So I tried the following but I get these errors.
dates is a 520000x1 cell array containing the dates form = formatIn.
formatIn = 'DD/MM/YYYY HH:MM:SS';
[~,M,D,H] = datevec(dates, formatIn);
Error using cnv2icudf (line 131) Unrecognized minute format.
Format string: DD/MM/YYYY HH:MM:SS.
Error in datevec (line 112) icu_dtformat = cnv2icudf(varargin{isdateformat});`
Assuming your data is in a matrix or cell-array of strings called A, and your other data is in a vector X. Let's say all the data is in the same year (so we can ignore years)
[~,M,D,H] = datevec(A, 'dd/mm/yyyy HH:MM:SS');
mean_A = accumarray([M, D, H+1], X, [], #mean);
Then data from February will be in
mean_A(2,:,:)
To look at the data, you may find the squeeze() function useful, e.g.
squeeze(mean_A(2,1:10,13:24))
shows the average for the hours after midday (by column) for the first ten days (by row) of February.
See also:
Counting values by day/hour with timeseries in MATLAB

Access datediff using calculated first day of the year

I'm creating a new form in Access 2010. I need to create a field that will calculate a year to date timeframe, in months, using a calculated value for the first day of the year. The scenario is that the user will input a date. Then, Access will calculate a value for months YTD, based on the date the user keys. The catch is that the user may input a date for the current year, or a date from a previous year. So, I cannot simply hard code a baseline date, like 1/1/2014, to perform the calculation. I need Access to generate the first day of the year, based on the date entered, then perform the calculation.
Example: User enters '4/10/2013'
Access calculates months YTD from '1/1/2013' to '4/10/2013'.
Expected Result: 3.25 Months
I need this to assist with calculating income, which will utilize dates over multiple years.
I quickly created this function for you:
Public Function calcmonths(datecalc As Date) As Double
calcmonths = Round(DateDiff("d", DateSerial(Year(datecalc), 1, 1), datecalc) * 12 / DateDiff("d", DateSerial(Year(datecalc), 1, 1), DateSerial(Year(datecalc) + 1, 1, 1)), 2)
End Function
You can use it with the input from your form. It calculates the first day of the entered year with DateSerial(Year(datecalc), 1, 1) , then calculates the difference in days. That result is multiplied by 12 (months) and divided by the number of days within that year (calculated to make sure leap years are 366 days). In the end the result is rounded to 2 decimal numbers.