Conditional cumulative sum in SAS - sas

I have been searching the solution a while, but I couldn't find any similar question in SAS in communities.
I have the following table in SAS. I need to get the cumulative value by Date. Most importantly, I need the cumulative value starts from new once it exceeds 10.
Date Number
01/01/2017 3
01/01/2017 1
01/01/2017 3
01/01/2017 4
01/01/2017 6
01/01/2017 8
02/01/2017 6
02/01/2017 3
02/01/2017 5
02/01/2017 7
03/01/2017 4
03/01/2017 3
... ...
I need my output table looks like this. Just one more column shows the cumulative values.
Date Number cumulative
01/01/2017 3 3
01/01/2017 1 4
01/01/2017 3 7
01/01/2017 4 4 <---- (starts from new)
01/01/2017 6 10
01/01/2017 8 8
02/01/2017 6 6
02/01/2017 3 9
02/01/2017 5 5
02/01/2017 7 7 <---- (starts from new)
03/01/2017 4 3
03/01/2017 3 7
... ... ...
Would someone be able to assist with this.
Thanks

Something like (untested):
data out;
set in;
by date; * Assumes sorted by date;
retain cumulative;
if first.date or cumulative+number > 10 then do;
cumulative = 0;
end;
cumulative = cumulative + number;
run;
should work...

Related

Google Sheets formula for summing/averaging with specific conditions

I am hoping for a formula to take hours from the name columns and sum/average them by week, into a separate table like the 2nd one below. The formulas need to update upon changing the start and end week cells.
Body Part
Start Week
End Week
Arnold (hours)
Usain (hours)
Bob (hours)
Arms
1
3
6
3
0
Legs
1
6
12
36
20
Chest
2
4
6
2
2
Booty
4
6
9
12
3
Core
1
5
10
5
5
Formula Needed:
Hours
Arnold
Usian
Bob
Week 1
6
8
4.33
Week 2
8
8.67
5
Week 3
8
8.67
5
Week 4
9
11.67
6
Week 5
7
11
5.33
Week 6
5
10
4.33
Bonus if there is a way to also quickly average hours by body parts if for example there are multiple Arms rows.
try:
=ARRAYFORMULA(LAMBDA(a, b, QUERY(SPLIT(FLATTEN(BYCOL(D1:F1, LAMBDA(xx, FLATTEN(IF(
IF(a>=SEQUENCE(1, MAX(a)), "Week "&TEXT(SEQUENCE(1, MAX(a))+b, "00"), )="",,
REGEXEXTRACT(OFFSET(xx,,,1), "(.+) \(")&"×"&
IF(a>=SEQUENCE(1, MAX(a)), "Week "&TEXT(SEQUENCE(1, MAX(a))+b, "00"), )&"×"&
QUERY({REGEXEXTRACT(OFFSET(xx,,,1), "(.+) \("); OFFSET(xx,1,,9^9)/(a)}, "offset 1", )))))), "×"),
"select Col2,sum(Col3) where Col3>0 group by Col2 pivot Col1"))
(C2:INDEX(C:C, MAX(ROW(C:C)*(C:C<>"")))-B2:INDEX(B:B, MAX(ROW(B:B)*(B:B<>"")))+1,
B2:INDEX(B:B, MAX(ROW(B:B)*(B:B<>"")))-1))

cumulative average powerbi by month

I have below dataset.
Math Literature Biology date student
4 2 5 2019-08-25 A
4 5 4 2019-08-08 A
5 4 5 2019-08-23 A
5 5 5 2019-08-15 A
5 5 5 2019-07-19 A
5 5 5 2019-07-15 A
5 5 5 2019-07-03 A
5 5 5 2019-06-26 A
1 1 2 2019-06-18 A
2 3 3 2019-06-14 A
5 5 5 2019-05-01 A
2 1 3 2019-04-26 A
I need to develop a solution in powerbi so in output I have cumulative average per subject per month
For example
April May June July August
Math | 2 3.5 3 3.75 4
Literature | 1 3 3 3.75 3.83
Biology | 3 4 3.6 4.125 4.33
Can you help?
You can use a matrix visualization for this.
Create a month-year variable and use it in the columns.
Use Average of Math,Literature and Biology in values
Under the format pane --> Values --> Show on rows --> Select this
This should give the view you are looking for. You can edit the value headers to your requirement.

remove/filter data from power bi modeling tab

I have a very large data set and would like to remove n rows from the bottom up.
For example, if I had 15 numbers: 1 1 2 3 4 5 5 6 7 7 7 8 8 9 9, and I want to remove 5 entries from the bottom, being 7 8 8 9 9.
How can I do this in dax, remove/filter out n rows from the bottom of my data?
Thanks

Finding the max(latest) date out of a column of dates then grouping them by employee

Importing the data frame
df = pd.read_csv("C:\\Users")
Printing the list of employees usernames
print (df['AssignedTo'])
Returns:
Out[4]:
0 vaughad
1 channln
2 stalasi
3 mitras
4 martil
5 erict
6 erict
7 channln
8 saia
9 channln
10 roedema
11 vaughad
Printing The Dates
Returns:
Out[6]:
0 2015-11-05
1 2016-05-27
2 2016-04-26
3 2016-02-18
4 2016-02-18
5 2015-11-02
6 2016-01-14
7 2015-12-15
8 2015-12-31
9 2015-10-16
10 2016-01-07
11 2015-11-20
Now I need to collect the latest date per employee?
I have tried:
MaxDate = max(df.FilledEnd)
But this just returns one date for all employees.
So we see multiple employees in the data set with different dates, in a new column named "LatestDate" I need the latest date that corresponds to the employee, so for "vaughad" in a new column it would return "2015-11-20" for all of "vaughad" records and in the same column for username "channln" it would return "2016-5-27" for all of "channln" latest dates.
You need to group your data first, using DataFrame.groupby(), after which you can produce aggregate values, like the maximum date in the FilledEnd series:
df.groupby('AssignedTo')['FilledEnd'].max()
This produces a series, with AssignedTo as the index, and the latest date for each of those employees as the values:
>>> df.groupby('AssignedTo')['FilledEnd'].max()
AssignedTo
channln 2016-05-27
erict 2016-01-14
martil 2016-02-18
mitras 2016-02-18
roedema 2016-01-07
saia 2015-12-31
stalasi 2016-04-26
vaughad 2015-11-20
Name: FilledEnd, dtype: object
If you wanted to add those max dates values back to the dataframe, use groupby(...).transform() with numpy.max instead, so you get a series with the same indices:
df['MaxDate'] = df.groupby('AssignedTo')['FilledEnd'].transform(np.max)
This adds in a MaxDate column:
AssignedTo FilledEnd MaxDate
0 vaughad 2015-11-05 2015-11-20
1 channln 2016-05-27 2016-05-27
2 stalasi 2016-04-26 2016-04-26
3 mitras 2016-02-18 2016-02-18
4 martil 2016-02-18 2016-02-18
5 erict 2015-11-02 2016-01-14
6 erict 2016-01-14 2016-01-14
7 channln 2015-12-15 2016-05-27
8 saia 2015-12-31 2015-12-31
9 channln 2015-10-16 2016-05-27
10 roedema 2016-01-07 2016-01-07
11 vaughad 2015-11-20 2015-11-20

Retain the cluster number for each member of a cluster within an id variable

I would like to label how many unique clusters of data are in a longitudinal dataset and have each member of the cluster carry the cluster count. Distinct clusters are those sharing a set of dates within an id. The order of those distinct cluster relative to previous (earlier) clusters creates the desired result. This coding is necessary to address the problem of event ordering required for a time-dependent covariate analysis.
input id date
1 28jan2015
1 28jan2015
2 26nov2015
3 19oct2015
4 26dec2015
5 23dec2015
6 22may2015
6 23sep2015
6 23sep2015
7 14jan2015
7 27feb2015
7 30may2015
8 16apr2015
8 16apr2015
8 16apr2015
8 16apr2015
8 16apr2015
9 17jul2015
9 03oct2015
9 03oct2015
10 27jul2015
end
I have attempted:
bys id (date): gen count_obs = [_n]
bys id date: gen count_interval_obs = [_n]
egen n_interval = group(id date)
resulting in accurate counts of the total number of observations per id and enumeration of the number of observations within a date. However, the egen function group() results in identifying each unique set of dates, but numbers the groups without regard to id, giving:
id wrong_cluster correct_cluster
1 28jan2015 1 1
1 28jan2015 1 1
2 26nov2015 2 1
3 19oct2015 3 1
4 26dec2015 4 1
5 23dec2015 5 1
6 22may2015 6 1
6 23sep2015 7 2
6 23sep2015 7 2
etc.
egen, group() cannot be used with the by: prefix.
Any assistance would be appreciated.
Todd
Edit: Added an explanation of why the cluster identification is necessary. Clarified what rule defines a cluster.
#Roberto Ferrer has given a direct approach. It follows from the logic he uses that there is also a route using egen's group() function:
egen group = group(id date2)
bysort id (group): gen clust2 = sum(group != group[_n-1])
For each id, when the date is different than the preceding observation, add 1 to the running sum. The 1 is realized when the condition inside sum() is met.
clear
set more off
input id str15 date
1 28jan2015
1 28jan2015
2 26nov2015
3 19oct2015
4 26dec2015
5 23dec2015
6 22may2015
6 23sep2015
6 23sep2015
7 14jan2015
7 27feb2015
7 30may2015
8 16apr2015
8 16apr2015
8 16apr2015
8 16apr2015
8 16apr2015
9 17jul2015
9 03oct2015
9 03oct2015
10 27jul2015
end
gen date2 = date(date, "DMY")
format %td date2
drop date
list, sepby(id)
*----- what you want -----
bysort id (date2) : gen clust = sum(date2 != date2[_n-1])
list, sepby(id)