Median-If With Month Criteria not working in LibreOffice - arrays

I have a simple spreadsheet like below, with columns:
A: Timestamp
B: A numerical result
C: Time duration to compute above result
I want to compute the median value for duration for year 2019 March in cell I4. I used the following formula for it:
{=MEDIAN(IF((YEAR(A:A) = G1) * (MONTH(A:A) = 3), C:C))}
I expect value 48.5 should appear (median value b/w 41 and 56). But, it's showing an error #VALUE! when entered using Ctrl-Shift-Enter.
Can someone point where the problem might be.

Related

Formula to write milliseconds in hh:mm:ss.000 format gives wrong values

I'm trying to convert duration in one column which is written in milliseconds (Ex: 600,2101,1110....) to hh:mm:ss.000 format(Ex:00:00:00.600, 00:00:02.101...) using the below formula in google spreadsheets:
=CONCATENATE(TEXT(INT(A1/1000)/86400,"hh:mm:ss"),".",A1-(INT(A1/1000)*1000))
It gives correct values for almost all , but one type of values which is durations having '0' as their second digit (Eg: 2010,3056,1011).
When 0 is the second digit , the after decimal value in hh:mm:ss.000 is rounded to the third digit and 0 is ignored (Example row 1 and 2 in below table). But for other durations it gives right value(row 3).
I need a formula that works well on all type of values i.e 1080 → 00:00:01.080 and not 00:00:01.80 .
Can someone please help with this.
Duration in milliseconds
hh:mm:ss.000 format
1080
00:00:01.80 (wrong)
2010
00:00:02.10 (wrong)
1630
00:00:01.630 (correct)
try:
=INDEX(IF(A2:A="",,TEXT(A2:A/86400000, "hh:mm:ss.000")))

Different results from STRREAD() for reading strings

I have a date cell array which is read from a csv file. The format is below:
date =
'2008.12.01'
'2008.12.02'
'2008.12.03'
'2008.12.04'
'2008.12.05'
... ...
And I want to:
turn the cell array to a string array,
use the strread() to read its "yyyy","mm" and "dd" value into 3 double array [year,mm,dd],
use the datenummx() to turn [year,mm,dd] into date seriel num.
After i use
date = char(date);
the date array become like this:
date =
2008.12.01
2008.12.02
2008.12.03
2008.12.04
2008.12.05
... ...
which I think the result is what i want...
But after I use the strread(), it gives me odd result.
[year,month,day]=strread(date,'%d%d%d','delimiter','.');
year =
-1
0
0
0
0
... ...
BUT if I use the code below, the strread() can give me the right answer:
s = sprintf('2008.12.01')
s =
2008.12.01
[year,month,day]=strread(s,'%d%d%d','delimiter','.')
year =
2008
month =
12
day =
1
And I checked in the matlab that both the "date" and "s" is a char array.(by using function 'ischar' and simply display both)...
But why do the strread() give differnt results?
Can anyone answer?
by the way, I use the MatLab v6.5.(for my own reason, so please don't comment by asking "why not use a higher version")....
Your problem is this line:
date = char(date);
It does not create an array of strings, there is no array of strings in matlab. It creates an array of chars. As you already noticed, your strread-line is fine if you input a single date, so input each date form your original cell array individually:
for idx=1:numel(date)
[year(idx),month(idx),day(idx)]=strread(date{idx},'%d%d%d','delimiter','.');
end
Preallocation of year, month and day improves the performance.

Sum(if) array in Excel 2013 for a range of columns

I have a matrix in Excel with a "Type" in column A and consecutive dates across Row 1.
On each day for each type, the result is either 1 or zero.
My goal is to use a Sum(if) array to sum the values for a particular type for a date range by inputting a start date value in B9 and an end date value in B10 for a specified type ("A", "B", "C") in B8.
Here is the function I've started: {=SUM((A2:A4=B8)*(IF(B1:F1=B9,B2:F4)))}
I'm having difficulty making the function assess the range specified in B9 and B10. Also, you should know that I've used numbers for the day, so use "4" in place of ie 2/4/2015.
Any thoughts?
This formula should help:
=SUMIFS(OFFSET(A1,MATCH(B8,A2:A4,0),1,1,5),B1:F1,">=" & B9,B1:F1,"<=" & B10)
The last parameter in OFFSET function (5) is number of columns in the sum (if the dates are in B1:F1, then it's 5)

Concatenating a numeric matrix with a 1xn cell

When trying the following concatenation:
for i=1:1:length(Open)
data(i,1) = Open(i);
data(i,2) = Close(i);
data(i,3) = High(i);
data(i,4) = Low(i);
data(i,5) = Volume(i);
data(i,6) = Adj_Close(i);
data(i,7) = cell2mat(dates(1,i));
end
Where all matrices but dates contain double values, and dates is a cell array with dates in the format '2001-01-01'. Running the code above, I get the following error:
??? Subscripted assignment dimension mismatch.
Error in ==> Test_Trades_part2 at 81
data(i,7) = cell2mat(dates(1,i));
The code above is tied to a master code which takes data from Yahoo Finance and then puts it in my SQL database.
A convenient way to store dates in completely numeric format is with datenum:
>> data(i,7) = datenum('2001-01-01');
>> disp(data(i,:))
0 0 0 0 0 0 730852
Whether this is useful to you depends on what you intend to do with the SQL database. Howeer, converting back to a string with MATLAB is straightforward with the datestr command:
>> datestr(730852,'yyyy-mm-dd')
ans =
2001-01-01
APPENDIX:
A serial date number represents a calendar date as the number of days that has passed since a fixed base date. In MATLAB, serial date number 1 is January 1, 0000.
Thank you all for the help!
I solved this issue using the following methodlogy (incorporating structs, should have thought of that .. stupid me):
data = [open, close_price, high, low, volume, closeadj];
s = struct('OpenPrice', data(:,1), 'ClosePrice', data(:,2), 'High', data(:,3), 'Low', data(:,4), 'Volume', data(:,5), 'Adj_Close', data(:,6), 'Dates', {dates});
This way, I enter all the values contained in the struct, circumventing the need to concatenate numeric and string matrices. Odd though, that is not allowed to have such matrices in on matrix; I would suppose that is the reason they created structs.

Functions within accumarray

If I have a column of dates and a column of data, I use this code to find the cumulative sum of the data for each of the dates, as found in the third column:
orgcumulative=cell2mat(accumarray(day,data,[],#(x){cumsum(x)}));
k=orgcumulative==0;
CVD=orgCVD;
CVD(k)=[];
31,3,3
31,2,5
31,1,6
31,5,11
07,2,2
07,3,4
07,4,9
07,2,11
07,3,14
07,5,19
07,3,22
07,1,23
07,1,24
07,2,26
07,3,29
30,5,5
06,4,4
Now I want to divide each data point within a day by the sum of the data within that day. For example:
31,3,3,3/11
31,2,5,2/11
31,1,6,1/11
31,5,11,5/11 <-- 11 is the sum of data for the 31 date
07,2,2,2/29
07,3,4, %and so on...
07,4,9,
07,2,11,
07,3,14,
07,5,19,
07,3,22,
07,1,23,
07,1,24,
07,2,26,
07,3,29, <-- 29 is the sum of data for the 07 date
30,5,5,1
06,4,4,1
If I try:
fractions=cell2mat(accumarray(day,data,[],#(x){ data/sum(x) }));
This will divide the entire second column by each of the sums. Is there a way to restrict this so the division only happens for the members of the second column within each day?
Would it not be easier to accumulate the total for each day using accumarray and then use the day array as an index when accessing the accumarray output, like so:
total = accumarray(day, data); % equivalent to accumarray(day, data, [], #sum)
fractions = data ./ total(day);

Resources