Skip to content

Using cumsum with 'group by' ?

9 messages · TheRealJimShady, arun, Pete Brecknock +1 more

#
Hi,
No problem.
One more method if you wanted to try:
library(data.table)
dat2<-data.table(dat1)
dat2[,list(x,time,Cumsum=cumsum(x)),list(id)]
?# ? id? x? time Cumsum
?#1:? 1? 5 12:01????? 5
?#2:? 1 14 12:02???? 19
?#3:? 1? 6 12:03???? 25
?#4:? 1? 3 12:04???? 28
?#5:? 2 98 12:01???? 98
?#6:? 2 23 12:02??? 121
?#7:? 2? 1 12:03??? 122
?#8:? 2? 4 12:04??? 126
?#9:? 3? 5 12:01????? 5
#10:? 3 65 12:02???? 70
#11:? 3 23 12:03???? 93
#12:? 3 23 12:04??? 116


A.K.



----- Original Message -----
From: TheRealJimShady <james.david.smith at gmail.com>
To: r-help at r-project.org
Cc: 
Sent: Thursday, November 22, 2012 12:27 PM
Subject: Re: [R] Using cumsum with 'group by' ?

Thank you very much, I will try these tomorrow morning.

On 22 November 2012 17:25, arun kirshna [via R]
<ml-node+s789695n4650459h55 at n4.nabble.com> wrote:
--
View this message in context: http://r.789695.n4.nabble.com/Using-cumsum-with-group-by-tp4650457p4650461.html
Sent from the R help mailing list archive at Nabble.com.
??? [[alternative HTML version deleted]]

______________________________________________
R-help at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
#
On Nov 23, 2012, at 12:04 , TheRealJimShady wrote:

            
Did you miss an 'e' on the first 'not'?? Otherwise, I'm confused.

Why do people always forget about ave()? I'd try

newdata <- transform(mydata, csum=ave(x, id, as.Date(date), FUN=cumsum))

You still need to sort, of course, at least by date (incl. time). Check carefully whether time zone is an issue for as.Date --- you may need the tz argument.

Also notice that I shy using an R function name as a variable name. This is mostly superstition these days, but better safe than sorry.

  
    
#
HI,

If that is the case, this should work:
dat1<-read.table(text="
id,????????? x,????????? date
1,????????? 5,????????? 2012-06-05 12:01
1,????????? 10,??????? 2012-06-05 12:02
1,????????? 45,??????? 2012-06-05 12:03
2,????????? 5,????????? 2012-06-05 12:01
2,????????? 3,????????? 2012-06-05 12:03
2,????????? 2,????????? 2012-06-05 12:05
3,????????? 5,????????? 2012-06-05 12:03
3,????????? 5,????????? 2012-06-05 12:04
3,????????? 8,????????? 2012-06-05 12:05
1,????????? 5,????????? 2012-06-08 13:01
1,????????? 9,????????? 2012-06-08 13:02
1,????????? 3,????????? 2012-06-08 13:03
2,????????? 0,????????? 2012-06-08 13:15
2,????????? 1,????????? 2012-06-08 13:18
2,????????? 8,????????? 2012-06-08 13:20
2,????????? 4,????????? 2012-06-08 13:21
3,????????? 6,????????? 2012-06-08 13:15
3,????????? 2,????????? 2012-06-08 13:16
3,????????? 7,????????? 2012-06-08 13:17
3,????????? 2,????????? 2012-06-08 13:18
",sep=",",header=TRUE,stringsAsFactors=FALSE)
dat1$date<-as.Date(dat1$date,format="%Y-%m-%d %H:%M")
?dat2<-dat1[order(dat1[,1],dat1[,3]),]
?dat2$Cumsum<-ave(dat2$x,list(dat2$id,dat2$date),FUN=cumsum)

head(dat2)
#?? id? x?????? date Cumsum
#1?? 1? 5 2012-06-05????? 5
#2?? 1 10 2012-06-05???? 15
#3?? 1 45 2012-06-05???? 60
#10? 1? 5 2012-06-08????? 5
#11? 1? 9 2012-06-08???? 14
#12? 1? 3 2012-06-08???? 17
#or
with(dat2,aggregate(x,by=list(id=id,date=date),cumsum))
#? id?????? date??????????? x
#1? 1 2012-06-05??? 5, 15, 60
#2? 2 2012-06-05???? 5, 8, 10
#3? 3 2012-06-05??? 5, 10, 18
#4? 1 2012-06-08??? 5, 14, 17
#5? 2 2012-06-08? 0, 1, 9, 13
#6? 3 2012-06-08 6, 8, 15, 17
A.K.



----- Original Message -----
From: TheRealJimShady <james.david.smith at gmail.com>
To: r-help at r-project.org
Cc: 
Sent: Friday, November 23, 2012 6:04 AM
Subject: Re: [R] Using cumsum with 'group by' ?

Hi Arun & everyone,

Thank you very much for your helpful suggestions. I've been working
through them, but have realised that my data is a little more
complicated than I said and that the solutions you've kindly provided
don't work. The problem is that there is more than one day of data for
each person. It looks like this:

id? ? ? ? ? x? ? ? ? ? date
1? ? ? ? ? 5? ? ? ? ? 2012-06-05 12:01
1? ? ? ? ? 10? ? ? ? 2012-06-05 12:02
1? ? ? ? ? 45? ? ? ? 2012-06-05 12:03
2? ? ? ? ? 5? ? ? ? ? 2012-06-05 12:01
2? ? ? ? ? 3? ? ? ? ? 2012-06-05 12:03
2? ? ? ? ? 2? ? ? ? ? 2012-06-05 12:05
3? ? ? ? ? 5? ? ? ? ? 2012-06-05 12:03
3? ? ? ? ? 5? ? ? ? ? 2012-06-05 12:04
3? ? ? ? ? 8? ? ? ? ? 2012-06-05 12:05
1? ? ? ? ? 5? ? ? ? ? 2012-06-08 13:01
1? ? ? ? ? 9? ? ? ? ? 2012-06-08 13:02
1? ? ? ? ? 3? ? ? ? ? 2012-06-08 13:03
2? ? ? ? ? 0? ? ? ? ? 2012-06-08 13:15
2? ? ? ? ? 1? ? ? ? ? 2012-06-08 13:18
2? ? ? ? ? 8? ? ? ? ? 2012-06-08 13:20
2? ? ? ? ? 4? ? ? ? ? 2012-06-08 13:21
3? ? ? ? ? 6? ? ? ? ? 2012-06-08 13:15
3? ? ? ? ? 2? ? ? ? ? 2012-06-08 13:16
3? ? ? ? ? 7? ? ? ? ? 2012-06-08 13:17
3? ? ? ? ? 2? ? ? ? ? 2012-06-08 13:18

So what I need to do is something like this (in pseudo code anyway):

- Order the data by the id field and then the date field
- add a new variable called cumsum
- calculate this variable as the cumulative value of X, but grouping
by the id and date (not date, not date and time).

Thank you

James





On 23 November 2012 03:54, arun kirshna [via R]
<ml-node+s789695n4650505h81 at n4.nabble.com> wrote:
--
View this message in context: http://r.789695.n4.nabble.com/Using-cumsum-with-group-by-tp4650457p4650538.html
Sent from the R help mailing list archive at Nabble.com.
??? [[alternative HTML version deleted]]

______________________________________________
R-help at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
#
TheRealJimShady wrote
Peter Dalgaard's suggestion works for me ...

lines<-"id x date time
1 5 2012-06-05 12:01 
1 10 2012-06-05 12:02 
1 45 2012-06-05 12:03 
2 5 2012-06-05 12:01 
2 3 2012-06-05 12:03 
2 2 2012-06-05 12:05 
3 5 2012-06-05 12:03 
3 5 2012-06-05 12:04 
3 8 2012-06-05 12:05 
1 5 2012-06-08 13:01 
1 9 2012-06-08 13:02 
1 3 2012-06-08 13:03 
2 0 2012-06-08 13:15 
2 1 2012-06-08 13:18 
2 8 2012-06-08 13:20 
2 4 2012-06-08 13:21 
3 6 2012-06-08 13:15 
3 2 2012-06-08 13:16 
3 7 2012-06-08 13:17 
3 2 2012-06-08 13:18 
"

# read in data
dat1<-read.table(textConnection(lines), header=TRUE,stringsAsFactors=FALSE) 

# build csum variable
newdata <- transform(dat1, csum=ave(x, id, as.Date(date), FUN=cumsum)) 

# order data (not really necessary)
newdata.ord <-newdata[order(dat1[,"id"],dat1[,"date"],dat1[,"time"]),]

Or have I misinterpreted your request?

HTH

Pete (B not D)



--
View this message in context: http://r.789695.n4.nabble.com/Using-cumsum-with-group-by-tp4650457p4650556.html
Sent from the R help mailing list archive at Nabble.com.
3 days later
#
On Nov 27, 2012, at 14:30 , TheRealJimShady wrote:

            
OK. ave() is originally designed to replace observations by their per-group average. It works by splitting the input vector into groups according to one or more factors, performing FUN on each group, and putting the result back in the original positions. The default for FUN is mean, but it doesn't need to be a scalar function; it also works with a FUN that returns a vector the same length as the input, such as FUN=cumsum.

The specification does not seem to allow a list() of grouping factors. It does work, but as it is unauthorised, it might not keep working.

Elaborating on the help page example:
[1] 44.55556 44.55556 44.55556 44.55556 44.55556 44.55556 44.55556 44.55556
 [9] 44.55556 24.00000 24.00000 24.00000 24.00000 24.00000 24.00000 24.00000
[17] 24.00000 24.00000 24.55556 24.55556 24.55556 24.55556 24.55556 24.55556
[25] 24.55556 24.55556 24.55556 28.22222 28.22222 28.22222 28.22222 28.22222
[33] 28.22222 28.22222 28.22222 28.22222 28.77778 28.77778 28.77778 28.77778
[41] 28.77778 28.77778 28.77778 28.77778 28.77778 18.77778 18.77778 18.77778
[49] 18.77778 18.77778 18.77778 18.77778 18.77778 18.77778
[1] 401 401 401 401 401 401 401 401 401 216 216 216 216 216 216 216 216 216 221
[20] 221 221 221 221 221 221 221 221 254 254 254 254 254 254 254 254 254 259 259
[39] 259 259 259 259 259 259 259 169 169 169 169 169 169 169 169 169
[1]  26  56 110 135 205 257 308 334 401  18  39  68  85  97 115 150 180 216  36
[20]  57  81  99 109 152 180 195 221  27  41  70  89 118 149 190 210 254  42  68
[39]  87 103 142 170 191 230 259  20  41  65  82  95 110 125 141 169
[1]  26  56 110 135 205 257 308 334 401  18  39  68  85  97 115 150 180 216  36
[20]  57  81  99 109 152 180 195 221  27  41  70  89 118 149 190 210 254  42  68
[39]  87 103 142 170 191 230 259  20  41  65  82  95 110 125 141 169