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)
Related
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.
I have an array that contains multiple dates in the format yyyymmdd, stored as a 50x1 double. I am trying to pull out the year,month, and day so I can use datenum to assign each date a serial number.
Indexing an individual date, converting the using str2num, then indexing and pulling the appropriate values works fine, but when I try to loop through the list of dates it doesn't work- only variations of the number 2 are returned.
dates = [20180910; 20180920; 20181012; 20181027; 20181103; 20181130; 20181225];
% version1
datesnums=num2str(dates); % dates is a list of dates stored as
integers
for i=1:length(datesnums)
pullyy=str2num(datesnums(1:4));
pullmm=str2num(datesnums(5:6));
pulldd=str2num(datesnums(7:8));
end
As well as
%version2
datesnums=num2str(dates,'%d')
for i = 1:length(datesnums)
dd=datenum(str2num(datesnums(i(1:4))),str2num(datesnums(i(5:6))),
str2num(datesnums(i(7:8))));
end
I'm trying to generate a new array that is just the serial numbers of the input dates. In the examples shown, I am only getting single integer values, which I know is because the loop is incorrect and I get errors that say "Index exceeds the number of array elements (1)." for version 1. When I've gotten it to successfully loop through everything, the outputs are just '2222','22,'22' for every single date which is incorrect. What am I doing wrong? Do I need to incorporate a cell array?
To get all the years, month, and days in a loop:
datesnums=num2str(dates);
for i=1:size(datesnums, 1)
pullyy(i) = str2num(datesnums(i,1:4));
pullmm(i) = str2num(datesnums(i,5:6));
pulldd(i) = str2num(datesnums(i,7:8));
end
Actually, you can do this without a loop:
pullyy = str2num(datesnums(:,1:4));
pullmm = str2num(datesnums(:,5:6));
pulldd = str2num(datesnums(:,7:8));
Explanation:
If for example the dates vector is a [6x1] array:
dates =[...
20190901
20170124
20191215
20130609
20141104
20190328];
Than datesnums=num2str(dates); creates a char matrix of size [6x8] where each row corresponds to one element in dates:
datesnums =
6×8 char array
'20190901'
'20170124'
'20191215'
'20160609'
'20191104'
'20190328'
So in the loop you need to refer to the row index for each date and and the column indices to extract the years, month, and days.
The easiest solution I can think of is:
SN = datenum(num2str(dates),'yyyymmdd')
You only have to specify the date format which is 'yyyymmdd'
I would like to look up a row (an array) based on the DATE value, such that an array of price value (instead of a single return if using VLOOKUP) is returned for a given DATE value. Below is the data
Column A Column B Column C Column D
Row1 DATE Product A Product B Product C
Row2 1/1/2017 1 5 7
Row3 7/1/2017 3 6 5
Row4 13/1/2017 2 8 3
Thank you in advance
So one way to do this would be to make the lookup row a relative value. So assuming that your sample data is on Sheet1 and the list of dates you are looking up against is on Sheet2 Col A with a header. I would first make the lookup range a named range so that Sheet1 Col A thru Col D is named something like "Data". Then in B2 place the below formula and copy it to over to Col D and then all the way down the list of dates.
=vlookup($A2,Data,Column(B1),False)
The $ for A2 allows it to always look at column A even when copying over the formula. The Column(B1) returns a value of 2 but when you copy that formula to the left it will change to Column(c1), Column(d1)... thus changing what column of data you want returned.
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.
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);