I have a large spreadsheet and I am struggling to get an average, no formula I have used thus far from google or otherwise, has worked.
The average is an average of time, in particular, hours between a start and end time, converted into days.
In column E9:E1833, I have start time as dd/mm/yyy hh:mm
In column J9:J1833, I have the time in days, from start to finish as [h]:mm (some are empty)
I have an auto filter setup to change with job type / area / status etc, and the result needs to change as data is filtered.
The following formula works, but does not recalculate:
{=AVERAGE(IF(MONTH(E9:E1833)=1,(J9:J1833)))}
The following formula works, but gives an incorrect result:
=AVERAGE(IF(MONTH(E1833)=1,SUBTOTAL(101,(J9:J1833))))
I have tried Offset, with similar results, and many of the "off-the-shelf" solutions produces #Div/0, #REF, #Value or fail to allow the entry altogether.
Any help would be much appreciated, preferably not in VBA, as I don't want to be lumbered with this spreadsheet forever. Thanks in advance.
Since you are going to be filtering, and want the result to change as you filter, just use the AGGREGATE function:
=AGGREGATE(1,3,J:J)
EDIT: Animation added in response to question
The values in the Values column can be times, although you may have to format the result of the AGGREGATE function (cell/numberformat) to show the result as [h]:mm
Note: GIF will play twice. To repeat, refresh the page
The following formula seems to work.
{=AVERAGE(IF(SUBTOTAL(9,(OFFSET(J9:J1833,ROW(J9:J1833)-MIN(ROW(J9:J1833)),0,1)))>0,(IF(MONTH(E9:E1833)=3,SUBTOTAL(9,(OFFSET(J9:J1833,ROW(J9:J1833)-MIN(ROW(J9:J1833)),0,1)))))))}
The SUBTOTAL(9,OFFSET part of the function returns an array where filtered numbers are 0, and visible numbers return their values. If you just averaged that array, you would get the wrong number because you would be averaging all those zeros. So the IF statement just creates an array that returns a FALSE for zero, which is not averaged.
An additional caution that gave me a headache as I was playing around, was you are also filtering on MONTH()=1. The issue with that is, blank cells return a January date, which means they will not be filtered by MONTH()=1
Related
I am working on the capstone project in of the Google Career Certificate in Data Analytics. I am using Microsoft Excel. I have to calculate the ride length based on the start and end ride times. I've inputted the formula =F2(end time)-D2(start time) which returns the ride length. Going through my entire list I have some areas where the start time is like 11pm and the end time is 1am and this is returning ###### because it is a negative number with the regular formula. I've found a modified formula that can kind of do the conversion I am looking for but it is still a bit problematic. The modified formula is =(F2-D2+(F2<D2))*24 and it seems to give an accurate ride length if I reformat the answer to number. The issue is the rest of my data is in time format and the modified ones are in number format. If I convert the number values to time, the ride length values are inaccurate.
It is tricky to make the numeric value change as well due to me using a formula. I can correct them one by one after I save Excel and it no longer stores the numbers as the formula, but there are lots of data points to change and that would be time consuming. I'm hoping to find a more concise way to solve this problem. Maybe with a better formula.
[Snippet of the chart 1
Just like everything in life, there are multiple ways to achieve things. I would have formatted the date and time into a single cell; but. if you're gathering the data from another source, that's understandable.
A simple IF statement here will work. IF the days are one apart, then take '1' day off the starting time, else do your original formula:
=IF(E4-C4=1,F4-(D4-1),F4-D4)
I have the following excel result:
I want to group the above result in groups based on sessions i.e. if the time gap between two successive timestamps is greater than 5 minutes, it must be a new row.
For example :
I need some formula to achieve this. As I'm fairly new to Excel this is causing to be a major headache for me. Please help me, if anyone knows how to do it or at least point me in a direction.
Thanks a ton !!!
Judging by your screenshot, it appears your timestamps are actually text values. Text by default is usually left aligned where as numbers are right aligned. You seem to have a space at the end of your time stamp suggesting that it is probably left aligned and therefore text. You can test it with the following formula which will return TRUE if its text.
=ISTEXT(P2)
where P2 is one of your time stamps.
CONVERT TIMESTAMPS TO TIME
There are a variety of ways to do this. Some will depend on system settings. Take a look at the following functions as each might be useable depending on your system. The first two are a guarantee, the last two are more dependent on system settings.
DATE
TIME
DATEVALUE
TIMEVALUE
Something important to remember here is that in excel dates are integers counting the days since 1900/01/01 with that date being 1. Time is stored as a decimal and represents fraction/percentage of a day. 24:00:00 is not a valid time in excel though some functions may work with it.
So in order to convert your time stamp in P2 I used the following formula to pull out the date:
=DATE(LEFT(P2,4),MID(P2,FIND("-",P2)+1,2),MID(P2,FIND(" ",P2)-2,2))
Basically it goes into the text and strips out the individual numbers for Year, Month and Day.
To pull out the time, I could have done the same procedure but elected to demonstrate the TIMEVALUE method which is a little more robust than DATEVALUE and not a subjective to system settings as much. With the following formula I stripped out the whole time code (MINUS"UTC"):
=TIMEVALUE(TRIM(MID(P2,FIND(" ",P2)+1,FIND("UTC",P2)-FIND(" ",P2)-1)))
I also made an assumption that you are not mixing and matching UTC with other time zones which means it can be ignored. Now to get DATE and TIME all in one cell, you just need to add the two formulas together to get:
=DATE(LEFT(P2,4),MID(P2,FIND("-",P2)+1,2),MID(P2,FIND(" ",P2)-2,2))+TIMEVALUE(TRIM(MID(P2,FIND(" ",P2)+1,FIND("UTC",P2)-FIND(" ",P2)-1)))
In the example at the end, I placed that formula in Q2 and copied down
DELTA TIME
Since you want to break your groups out based on a time difference between individual entries, I used a helper column to store the time difference. In my example at the end I stored this difference in Column S. The first entry is blank as there is no time before it. I used the following formula in S3 and copied it downward.
=Q3-Q2
I applied the custom formatting of [h]:mm:ss to the cell to get it to display as shown.
FIND GROUP BREAK POINTS
In my example I am using helper column T to hold breakpoint flags. At a minimum, you will have two break points. Your first time entry and your last time entry. To make like simple I simply hard coded my first breakpoint flag in T2 as 1. Stating in T3, Three checks need to be made. If any of them are TRUE then the next flag needs to be added with a value increase by one. the three checks are:
Is this the last entry
Is the next time delta greater than 5 minutes (means end of a group)
Is this time delta greater than 5 minutes (means start of a group)
Based on those three checks I placed the following formula in T3 and copied down:
=IF(OR(S4="",S4>TIME(0,5,0),S3>TIME(0,5,0)),MAX($T$2:T2)+1,"")
Note the $ on the first part of the range for the MAX function. This will lock the start of the range while the formula gets copied down while the end of the range increases accordingly.
Also the row after the last time entry must be blank. IF it is not blank and has a set value in it, change the S4="" to S4="set value".
GENERATE TABLE
There are multiple ways to reference the flags and pull the corresponding times. a couple of formulas you can look into are:
INDEX / MATCH
LOOKUP
In this example I elected to use LOOKUP though I believe INDEX and MATCH are more appropriate and robust. For starters we want to generate a list of ODD number and EVEN numbers. These represent the start and end of the groups and correspond to the flags set in column T. One way to generate ODD and EVEN numbers as you copy down is:
=ROW(A1)*2-1 (ODD)
=ROW(A1)*2 (EVEN)
The next step is to find the generated number in Column T and then pull its corresponding timestamp in Column Q. I did this with the following formula in V2 and copied down.
=LOOKUP(ROW(A1)*2-1,T:T,Q:Q)
And in W2
=LOOKUP(ROW(A1)*2,T:T,Q:Q)
I have a gate keeping report with a number of entry/exit times for an employee over a 24hr period.
I need another formula to go into I40 which is the difference between the first entry time - last entry time for each employee eg. I40 = F50 - D40.
Dont worry about the formula regarding the subtraction of dates as I have this. I really just need the formula that will allow me to get the Last Exit time cell and the First Entry time cell for each employee.
The best way is to always store datetime values (ie, 2018-05-24 13:454) instead of just the times. You could still display it as a time by changing the cell's formatting to a time format.
Shortcut to Number Formatting options: Ctrl+1
There are many advantages, including that "regular math" will still work even if a shift starts in a different day than it ends.
If you must stick with only times, you can still calculate it correctly (up to a 23.9-hour shift) with an IF statement to add a day if the returned value is negative.
For example, if your existing formula works for same-day shift, and is:
=F50-D40
...then you could change it to:
=IF(F50-D40<0,F50+1-D40,F50-D40)
More Information:
Office.com : How to use dates and times in Excel
Office.com : Add or subtract time (Excel)
EDIT:
Looking at your question again, perhaps I misunderstood what you were trying to ndo. It's a little unclear, but you mention the fist and last times.
If you mean the "earliest and latest", you can get those using MIN and MAX. If the crossing-midnight is an issue here too, you'll need to see my first suggestion above, or else add a "helper column" to determine which times are before which.
Storing datetime is still best and this all would have been avoided.
try the below to get the difference in hours.
=(E50+F50)-(C40+D40)
I'm trying to perform an AVERAGEIFS formula on some data, but there are 2 possible results and as far as I can tell AVERAGEIFS doesn't deal with that situation.
I basically want to have an ELSE inside it.
At the moment I have 2 ranges of data:
The first column only contains values 'M-T' and 'F' (Mon-Thurs and Fri).
The second column contains a time.
The times on the rows with an 'F' value in column 1 are an hour behind the rest.
I want to take an average of all the times, adjusting for the hour delay on Fridays.
So for example I want it to take an average of all the times, but subtract 1 hour from the values which are in a row with an 'F' value in it.
The way I've been doing it so far is by having 2 separate results for each day, then averaging them again for a final one:
=AVERAGEIFS(G3:G172, B3:B172, "M-T")
=AVERAGEIFS(G3:G172, B3:B172, "F")
I want to combine this into just one result.
The closest I can get is the following:
=AVERAGE(IF(B3:B172="M-T",G3:G172,((G3:G172)-1/24)))
But this doesn't produce the correct result.
Any advice?
Try this
=(SUMPRODUCT(G3:G172)-(COUNTIF(B3:B172,"=F")/24))/COUNTIF(B3:B172,"<>""""")
EDIT
Explaining various steps in the formula as per sample data in the snapshot.
SUMPRODUCT(G3:G17) sums up all the value from G3 to G17. It gives a
value of 4.635416667. This after formatting to [h]:mm gives a value
of 111.15
OP desires that Friday time be one hour less. So I have kept one hour less for Friday's in the sample data. Similar SUMPRODUCT on H3:H17 leads to a value of 4.510416667. This after formatting to [h]:mm gives a value
of 108.15. Which is exactly three hours less for three occurrences of Fridays in the sample data.
=COUNTIF(B3:B17,"=F") counts the occurrences of Friday's in the B3:B17 range which are 3 occurrences.Hence 3 hours have to less. These hours are to be represented in terms of 24 hours hence the Function COUNTIF() value is divided by 24. This gives 0.125. Same is the difference of 4.635416667 and 4.510416667 i.e. 0.125
Demonstration column H is for illustrative purposes only. Infact Friday accounted values that is 108.15 in sample data has to be divided by total data points to get the AVERAGE. The occurrences of data points are calculated by =COUNTIF(B3:B17,"<>""""") with a check for empty columns.
Thus 108:15 divided by 15 data points give 7:13 in the answer.
Revised EDIT Based upon suggestions by #Tom Sharpe
#TomSharpe has been kind enough to point the shortcomings in the method proposed by me. COUNTIF(B3:B172,"<>""""") gives too many values and is not advised. Instead of it COUNTA(B3:B172) or COUNT(G3:G172) are preferable. Better Formula to get AVERAGE as per his suggestion gives very accurate results and is revised to:
=AVERAGE(IF(B3:B172="M-T",G3:G172,((G3:G172)-1/24)))
This is an Array Formula. It has to be entered with CSE and further cell to be formatted as time.
If your column of M-T and F is named Day and your column of times is named TIME then:
=SUMPRODUCT(((Day="M-T")*TIME + (Day="F")*(TIME-1/24)))/COUNT(TIME)
One simple solution would be to create a separate column that maps the time column and performs the adjustment there. Then average this new column.
Is that an option?
Ended up just combining the two averageifs. No idea why I didn't just do that from the start:
=((AVERAGEIFS(G$3:G171, $B$3:$B171, "F")-1/24)+AVERAGEIFS(G$3:G171, $B$3:$B171, "M-T"))/2
I'm trying to create a simple leave planner application using Sharepoint. I've got the bulk of it working but I'm going back to do edge cases now like Bank Holidays and half days. So I've added a checkbox column and if ticked, I want it to deduct 0.5 from the total value (half-day). The formula that's working for the full days is:
=(DATEDIF(dateFrom,dateTo,"D"))-INT(DATEDIF(dateFrom,dateTo,"D")/7)*2-IF((WEEKDAY(dateTo)-WEEKDAY(dateFrom))<0,2,0)+1
So I just created another two columns called shalfday and ehalfday. If they're ticked then deduct 0.5 from the total (If dates match and both ticked then deduct 0.5 still).
I've tried playing round with things like
-IF([shalfday],"0.5")
and other variants as google results are not being too kind this morning but they're returning #NAME? variables.
Any pointers on the syntax or what I should be looking at?
I would suggest:
-IF([shalfday],0.5,0)
Since you are trying to subtract you should work with integers and not strings (i removed the quotation marks).
I ended up doing this another way. I instead asked the user to specify how many half days were in their leave in another site column and used this suffix in the formula. It also got rid of the validation check to make sure the user wasn't taking two half days on 1 days leave.
New site column called 'Total Half Days' set to number, default value of 0;
Appended to original formula:
-([Total Half Days]/2)+1
Full formula:
=(DATEDIF(dateFrom,dateTo,"D"))-INT(DATEDIF(dateFrom,dateTo,"D")/7)*2-IF((WEEKDAY(dateTo)-WEEKDAY(dateFrom))<0,2,0)-([Total Half Days]/2)+1