how to count elements in google spreadsheets matching a certain date range - google-sheets

I have some data in columns with a timestamp in the first column and data columns.
A B C D
+++++++++++++++++++++++++++++++++++
20.5.2011 1 2 5
18.5.2011 3 5 4
12.5.2013 4 7 5
I am able to successfully filter columndata based on the timestamp with this google spreadsheets formula. The below returns a sum of all integers in column B if there is a corresponding 2011 timestamp.
=ArrayFormula(SUMIF(TEXT($A:$A;"yyyy");year(today())-1;$B:$B))
the above sums up the values 1 and 3 from column b and returns 4
The question is, how would I calculate the average for the above values 1 and 3 resulting in 2? My current approach is to divide the above formula by the count() of items that match the date criterion but I cannot get it to work.
=ArrayFormula(SUMIF(TEXT($A:$A;"yyyy");year(today())-1;$B:$B))/WFORMULA FOR THE DIVISOR
Any ideas?

You can use COUNTIF in much the same way as you used SUMIF:
=ArrayFormula(SUMIF(TEXT($A:$A;"yyyy");YEAR(TODAY())-1;$B:$B)/COUNTIF(TEXT($A:$A;"yyyy");YEAR(TODAY())-1))
(this would currently return the average of all the 2012 entries).
You can simplify this a little by using the YEAR function in the comparison array:
=ArrayFormula(SUMIF(YEAR($A:$A);YEAR(TODAY())-1;$B:$B)/COUNTIF(YEAR($A:$A);YEAR(TODAY())-1))
You can also generate a table of sums, averages or counts quite easily with QUERY:
=QUERY(A:B;"select year(A), avg(B) where A is not null group by year(A) label year(A) 'Year', avg(B) 'Average'")
and if you just wanted the average for 2012 as a single value:
=QUERY(A:B;"select avg(B) where year(A) = "&(YEAR(TODAY())-1)&" group by year(A) label avg(B) ''")

Related

Count of items in column A not in column B (Google sheets)

I have two columns of numbers in Google sheets. I’m trying to find a formula to give me a count of items in column A that are not in column B. The numbers in the columns are descending and unique in each column but can be duplicated across columns. The columns can also have different amounts of items in them.
Column A has 5 4 3 1
Column B has 4 2 1
The answer is this case would be 2 as the numbers 5 and 3 in column A are not in column B.
I’ve tried using sum, if and countif but can’t come up with a solution. Also not sure if this would be an array formula or not.
Without a helper column you can use reduce and lambda functions.
=reduce(0, A:A, LAMBDA(prev, a_value, prev + if(not(a_value = ""), iferror(min(0, match(a_value, B:B, false)), 1), 0)))
Fill column c with this formula:
=iferror(min(0,match(A1,B:B,false)),1)
If A1 is in column b the match function will return an value, which is then reduced to 0 by the min function. Otherwise match will return an error, and the iferror will return 1.
Then you just need to sum column c.

How to get the total number of counts for last not null date in google sheets based on another column?

This is a follow up question to:
How to get the total number of counts for last not null date in google sheets?
Question
How to get the most recent number of companies that I have applied?
For example, in the google sheet below, I have applied to 5 companies in last date of march4, so the answer is 5.
NOTE: there are 8 values for march4 but only 5 companies are not-empty.
Public sheet
https://docs.google.com/spreadsheets/d/10NzbtJhQj4hQBnZXcmwise3bLBIAWrE0qwSus_bz7a0/edit#gid=517697699
Try this:
=query({B2:C},"select Col1 where Col1 is not null order by Col2 desc limit "&countifs(C:C,max(C:C),B:B,"<>")&" ",0)
To get the number of companies on the most recent applied date:
=countifs(C:C,max(C:C),B:B,"<>")
It counts how many times the max() date occurs in Col C, where Col B has a value.
"<>" is used to denote 'not empty'.

Google sheets binning and group by (custom time interval)

I wish to count events that occurred within a custom time interval : it could be within 24h, or within a week or 2-months span.
I am using google sheets: I can create a pivot table and group by month, however I'd like to explore insights using custom intervals (I'm looking for pattern in epilepsy).
As final result, I wanna have a table that, for each day, it is reported the number of frequencies within that interval.
Particularly, I wanna focus on the interval of 24h to count the number of events of epilepsy (known as cluster seizures).
And then, on custom days intervals to explore periodicity or trends - like each 48 hours, or each 15 or 30 days.
See a mockup of Google Sheet here:
https://docs.google.com/spreadsheets/d/1tCxYV5mUcq6vKm8-fL-0HUAOjcB9fipLCqPD2Znv-X0/edit#gid=1372548551
I tried this attempts:
find out how many events occurred in the last 30 days prior to the reported date:
= IFERROR(
QUERY(
A:E,
"SELECT COUNT(A)
WHERE
A IS NOT NULL AND
E = FALSE AND
A >= date '" &
TEXT(
A2-30,
"yyyy-MM-dd"
) &"' AND
A <= date '" &
TEXT(
A2,
"yyyy-MM-dd"
) &"'
LABEL COUNT(A) '' "), "N/A")
Then, dragging the cell, I get the column "# events in the prior 30 days".
It works but seems a bit messy - especially for updating the intervals.
I tried this other approach:
=query(B:E, "select B, count(E), -1+count(E) where E = FALSE group by B label B 'Date with Clusters', count(E) 'Cluster seizures '")
That produces the last table.
I like this approach better, but here I am just grouping by the same date, without possibility to have a custom interval.
As an example, I will have that two events will be counted within the same day, not withing the same 24h interval.
Could you tell a better approach to handle datetime differences, so to create binning and group by with custom intervals ?
Below an example:
on the left table, data in input; on the middle column, result of first approach; on the right table, results of second approach.
given the table:
in order to group stuff with QUERY we need to "fix" the A column in order to get a custom period. lets say we need to group events every 3 weeks (21 days). we take the lowest and highest date and create a sequence with all the dates in between.
=INDEX(ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A))))
then we use running total on it to get every date which is 21 days apart from the previous/next one. we could use simple SEQUENCE (for min>max) to create this array but with SEQUENCE we cant go "back in time" (for max>min) so we use MMULT and negative number
therefore, to start from a frame of the first date and create 3 weeks group by windows (eg. min>max) we use:
=ARRAYFORMULA({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SiGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))})
and to get a reverse of it and start from frame of end date and create 3 weeks windows backwards (eg. max>min) we use:
=ARRAYFORMULA({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SiGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))})
at this stage, we can start fixing the A column via VLOOKUP and 4th argument set to 1 - approximate mode (instead of 0 - exact match mode) so forward in time will be:
=ARRAYFORMULA(IFNA(VLOOKUP(A2:A; SORT({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1)))
and backward in time shall be:
=ARRAYFORMULA(IFNA(VLOOKUP(A2:A; SORT({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1)))
and now we just create a virtual array {} and pair fixed column A with column C and input it as range into QUERY
side note:
to put columns next to each other in english spreadsheets we use ,
to put columns next to each other in non-english spreadsheets we use \
=ARRAYFORMULA(QUERY({IFNA(VLOOKUP(A2:A; SORT({MIN(A2:A); MIN(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1))\ C2:C};
"select Col1,count(Col1)
where Col2 = FALSE
group by Col1
order by count(Col1) desc
label count(Col1)''"))
and backwards in time:
=ARRAYFORMULA(QUERY({IFNA(VLOOKUP(A2:A; SORT({MAX(A2:A); MAX(A2:A)+MMULT(TRANSPOSE((
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))<=TRANSPOSE(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))*-21); SIGN(
ROW(INDIRECT(MIN(A2:A)&":"&MAX(A2:A)))))}); 1; 1))\ C2:C};
"select Col1,count(Col1)
where Col2 = FALSE
group by Col1
order by count(Col1) desc
label count(Col1)''"))
demo spreadsheet

Google Sheet sum and multiply numbers based on dates

I am trying to sum the packages(B) if dates are equal, then compare this sum with the Orders per Day column(C) and multiply by the Rate Per Package(D) depending where the sum falls within the Orders per Day number.
I would like to return just the total number if possible.
DEMO:
https://docs.google.com/spreadsheets/d/1oSFnjogyXYybsqIYgQW2m45bbyAVBTKr3EVgxcGWFQo/edit?usp=sharing
You can try the following 2 formulas
In cell F2 place
=QUERY({A2:D},"select Col1, sum(Col2)
where Col1 is not null
group by Col1 label sum(Col2)''",0)
Then in cell H2 use
=ArrayFormula(IFS(G2:G>=80,G2:G*D9,
G2:G>=59,G2:G*D8,
G2:G>=39,G2:G*D7,
G2:G>=19,G2:G*D6,
G2:G>=14,G2:G*D5,
G2:G>=9,G2:G*D4,
G2:G>=4,G2:G*D3,
G2:G=1,G2:G*D2,
G2:G="",""))
(You can adjust ranges to your needs)
Functions used:
QUERY
ArrayFormula
IFS

How to SUM rows filtered by multiple criteria

Google Sheets question.
I have the following sheet (named "x") containing expenses:
Date Sum Category
1/Jan/2017 100 red
2/Jan/2017 200 blue
3/Jan/2017 10 red
4/Jan/2017 20 blue
1/Feb/17 1 red
2/Feb/17 2 blue
I need to compute monthly totals, per category:
Month Red Blue
Jan/17 110 220
Feb/17 1 2
My current solution is to place in each result cell something like:
=SUM(IFERROR(FILTER(x!$B:$B, MONTH(x!$A:$A)=MONTH($A2), x!$C:$C="red")))
I am asking if there is a better way. I want to have a single result formula working over an array (maybe an ArrayFormula?!) instead of placing and customizing my formula in each cell.
Any ideas?! Thanks!
Well this is the basic idea of using pivot tables but not quite there because I can only get the month as a number so far
query(A:C,"select month(A)+1,sum(B) where C<>'' group by month(A) pivot C label month(A)+1 'Month Number'")
EDIT
The month number can be changed to a month name using an array formula and VLOOKUP but the formula is getting a bit long (my table of month numbers and names is in columns I & J)
=arrayformula({vlookup(query(query(A:C,"select month(A)+1,sum(B) where C<>'' group by month(A) pivot C label month(A)+1 'Month Number'"),"select Col1"),I:J,2,false)})
and you've still got to pick up the other two columns - this is the whole thing
=arrayformula({vlookup(query(query(A:C,"select month(A)+1,sum(B) where C<>'' group by month(A) pivot C label month(A)+1 'Month Number'"),"select Col1"),I:J,2,false),query(query(A:C,"select month(A)+1,sum(B) where C<>'' group by month(A) pivot C label month(A)+1 'Month Number'"),"select Col2,Col3")})

Resources