[R] Generating a "conditional time" variable
Finak Greg
Greg.Finak at ircm.qc.ca
Sat May 9 21:11:12 CEST 2009
Assuming the year column has complete data and doesn't skip a year, the following should take care of 1)
#Simulated data frame: year from 1990 to 2003, for 5 different ids, each having one or two eif "events"
test<-data.frame(year=rep(1990:2003,5),id=gl(5,length(1990:2003)),eif=as.vector(sapply(1:5,function(z){a<-rep(0,length(1990:2003));a[sample(1:length(1990:2003),sample(1:2,1))]<-1;a})))
#Generate the "conditional_time" column.
test<-do.call("rbind",lapply(split(test,test$id),function(z){s<-0;data.frame(z,cond_time=sapply(z$eif,function(i)ifelse(i==1,s<-1,s<<-s+1)))}))
Generally sapply, lapply, and apply are faster than "for" loops. split() will split your data frame by the $id column (second argument). lapply() loops through the resulting list and generates the cond_time variable, resetting when eif==1, otherwise incrementing the count, much as you have in your code.
If I understand 2) correctly, the following should do the trick:
test2<-test; #copy the data frame
test2<-do.call("rbind",lapply(split(test,test$id),function(z)z[1:which(z$eif==1)[1],]))
Similar to the former, but sub-setting the rows of the data data frame up to the first event, for each id.
If the above is all you need, then 1) and 2) could be combined in a single call.
Others will likely have a different approach..
Cheers,
--
Greg Finak
Post-Doctoral Research Associate
Computational Biology Unit
Institut des Recherches Cliniques de Montreal
Montreal, QC.
On 09/05/09 1:40 PM, "Vincent Arel-Bundock" <vincent.arel at gmail.com> wrote:
Hi everyone,
Please forgive me if my question is simple and my code terrible, I'm new to
R. I am not looking for a ready-made answer, but I would really appreciate
it if someone could share conceptual hints for programming, or point me
toward an R function/package that could speed up my processing time.
Thanks a lot for your help!
##
My dataframe includes the variables 'year', 'id', and 'eif' and has +/- 1.9
million id-year observations
I would like to do 2 things:
-1- I want to create a 'conditional_time' variable, which increases in
increments of 1 every year, but which resets during year(t) if event 'eif'
occured for this 'id' at year(t-1). It should also reset when we switch to a
new 'id'. For example:
dataframe = test
year id eif conditional_time
1990 1010 0 1
1991 1010 0 2
1992 1010 1 3
1993 1010 0 1
1994 1010 0 2
1995 1010 0 3
1996 1010 0 4
1997 1010 1 5
1998 1010 0 1
1999 1010 0 2
2000 1010 0 3
2001 1010 0 4
2002 1010 0 5
2003 1010 0 6
1990 2010 0 1
1991 2010 0 2
1992 2010 0 3
1993 2010 0 4
1994 2010 0 5
1995 2010 0 6
1996 2010 0 7
1997 2010 0 8
1998 2010 0 9
1999 2010 0 10
2000 2010 0 11
2001 2010 1 12
2002 2010 0 1
2003 2010 0 2
-2- In a copy of the original dataframe, drop all id-year rows that
correspond to years after a given id has experienced his first 'eif' event.
I have written the code below to take care of -1-, but it is incredibly
inefficient. Given the size of my database, and considering how slow my
computer is, I don't think it's practical to use it. Also, it depends on
correct sorting of the dataframe, which might generate errors.
##
for (i in 1:nrow(test)) {
if (i == 1) { # If first id-year
cond_time <- 1
test[i, 4] <- cond_time
} else if ((test[i-1, 1]) != (test[i, 4])) { # If new id
cond_time <- 1
test[i, 4] <- cond_time
} else { # Same id as previous row
if (test[i, 3] == 0) {
test[i, 4] <- sum(cond_time, 1)
cond_time <- test[i, 6]
} else {
test[i, 4] <- sum(cond_time, 1)
cond_time <- 0
}
}
}
--
Vincent Arel
M.A. Student, McGill University
[[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.
More information about the R-help
mailing list