Hi, I have a dataset which contains several time records for a number of days, plus a variable (light) that allows to determine night time (lihgt= 0) and daytime (light> 0). I need to obtain get dusk time and dawn time for each day and place them in two columns. This is the starting point (d): day time light 1 1 20 1 12 10 1 11 6 1 9 0 1 6 0 1 12 0 ... 30 8 0 30 3 0 30 8 0 30 3 0 30 8 8 30 9 20 And this what I want to get: day time light dusk dawn 1 1 20 11 10 1 12 10 11 10 1 11 6 11 10 1 9 0 11 10 1 6 0 11 10 1 12 0 11 10 ... 30 8 0 9 5 30 3 0 9 5 30 8 0 9 5 30 3 0 9 5 30 8 8 9 5 30 9 20 9 5 This is the code for data frame d: day= rep(1:30, each=10) n= length(dia); x= c(1:24) time= sample(x, 300, replace= T) light= rep(c(20,10,6,0,0,0,0,0,8,20), 30) d=data.frame(day,time,light) I'd need to impose a double condition like the next but if does not take more than one: attach(d) for (i in 1: n){ if (light[i-1]>2 & light[i]<2){ d$dusk<- time[i-1] } if (light[i-1]<2 & light[i]>2){ d$dawn<- time[i] } } detach(d) d Thank you for your help [[alternative HTML version deleted]]
No idea of how to do what you want but your data set is not working. I think that you want x= c(1:24) day= rep(1:30, each=10) time= sample(x, 300, replace= T) light= rep(c(20,10,6,0,0,0,0,0,8,20), 30) d=data.frame(day,time,light) n= length(day) John Kane Kingston ON Canada> -----Original Message----- > From: sguallar at yahoo.com > Sent: Sun, 15 Jul 2012 09:32:33 -0700 (PDT) > To: r-help at r-project.org > Subject: [R] Imposing more than one condition to if > > Hi, > > I have a dataset which contains several time records for a number of > days, plus a variable (light) that allows to determine night time (lihgt> 0) and daytime (light> 0). I need to obtain get dusk time and dawn time > for each day and place them in two columns. > > This is the starting point (d): > day time light > 1 1 20 > 1 12 10 > 1 11 6 > 1 9 0 > 1 6 0 > 1 12 0 > ... > 30 8 0 > 30 3 0 > 30 8 0 > 30 3 0 > 30 8 8 > 30 9 20 > > > And this what I want to get: > day time light dusk dawn > 1 1 20 11 10 > 1 12 10 11 10 > 1 11 6 11 10 > 1 9 0 11 10 > 1 6 0 11 10 > 1 12 0 11 10 > ... > 30 8 0 9 5 > 30 3 0 9 5 > 30 8 0 9 5 > 30 3 0 9 5 > 30 8 8 9 5 > 30 9 20 9 5 > > This is the code for data frame d: > day= rep(1:30, each=10) > n= length(dia); x= c(1:24) > time= sample(x, 300, replace= T) > light= rep(c(20,10,6,0,0,0,0,0,8,20), 30) > d=data.frame(day,time,light) > > I'd need to impose a double condition like the next but if does not take > more than one: > attach(d) > for (i in 1: n){ > if (light[i-1]>2 & light[i]<2){ > d$dusk<- time[i-1] > } > if (light[i-1]<2 & light[i]>2){ > d$dawn<- time[i] > } > } > detach(d) > d > > Thank you for your help > [[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.____________________________________________________________ GET FREE SMILEYS FOR YOUR IM & EMAIL - Learn more at http://www.inbox.com/smileys Works with AIM?, MSN? Messenger, Yahoo!? Messenger, ICQ?, Google Talk? and most webmails
Hello, There are obvious bugs in your code, you are testing for light > 2 or ligth < 2 but this would mean that dusk and dawn are undetermined for light == 2 and that they happen at light == 1. Without loops or compound logical conditions: f <- function(x){ x$dawn <- x$time[ which.min(x$light) ] x$dusk <- x$time[ max(which(x$light == 0)) + 1 ] x } do.call(rbind, by(d, d$day, f)) Hope this helps, Rui Barradas Em 15-07-2012 17:32, Santiago Guallar escreveu:> Hi, > > I have a dataset which contains several time records for a number of days, plus a variable (light) that allows to determine night time (lihgt= 0) and daytime (light> 0). I need to obtain get dusk time and dawn time for each day and place them in two columns. > > This is the starting point (d): > day time light > 1 1 20 > 1 12 10 > 1 11 6 > 1 9 0 > 1 6 0 > 1 12 0 > ... > 30 8 0 > 30 3 0 > 30 8 0 > 30 3 0 > 30 8 8 > 30 9 20 > > > And this what I want to get: > day time light dusk dawn > 1 1 20 11 10 > 1 12 10 11 10 > 1 11 6 11 10 > 1 9 0 11 10 > 1 6 0 11 10 > 1 12 0 11 10 > ... > 30 8 0 9 5 > 30 3 0 9 5 > 30 8 0 9 5 > 30 3 0 9 5 > 30 8 8 9 5 > 30 9 20 9 5 > > This is the code for data frame d: > day= rep(1:30, each=10) > n= length(dia); x= c(1:24) > time= sample(x, 300, replace= T) > light= rep(c(20,10,6,0,0,0,0,0,8,20), 30) > d=data.frame(day,time,light) > > I'd need to impose a double condition like the next but if does not take more than one: > attach(d) > for (i in 1: n){ > if (light[i-1]>2 & light[i]<2){ > d$dusk<- time[i-1] > } > if (light[i-1]<2 & light[i]>2){ > d$dawn<- time[i] > } > } > detach(d) > d > > Thank you for your help > [[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. >
try this:> set.seed(1) > day= rep(1:30, each=10) > n= length(day); x= c(1:24) > time= sample(x, 300, replace= T) > light= rep(c(20,10,6,0,0,0,0,0,8,20), 30) > d=data.frame(day,time,light) > > # create a dawn/dusk column to mark where it happens > d$dawn <- c(FALSE, (head(d$light, -1) < 2) & (tail(d$light, -1) > 2)) > d$dusk <- c((head(d$light, -1) > 2) & (tail(d$light, -1) < 2), FALSE) > > # now split and recombine to get the values for the day > result <- do.call(rbind, lapply(split(d, d$day), function(.day){+ # create new dataframe with the values + cbind(.day[, c('day', 'time', 'light')] + , dawn = .day$time[.day$dawn] + , dusk = .day$time[.day$dusk] + ) + }))> > > > resultday time light dawn dusk 1.1 1 7 20 16 14 1.2 1 9 10 16 14 1.3 1 14 6 16 14 1.4 1 22 0 16 14 1.5 1 5 0 16 14 1.6 1 22 0 16 14 1.7 1 23 0 16 14 1.8 1 16 0 16 14 1.9 1 16 8 16 14 1.10 1 2 20 16 14 2.11 2 5 20 10 17 2.12 2 5 10 10 17 2.13 2 17 6 10 17 2.14 2 10 0 10 17 2.15 2 19 0 10 17 2.16 2 12 0 10 17 2.17 2 18 0 10 17 2.18 2 24 0 10 17 2.19 2 10 8 10 17 2.20 2 19 20 10 17 3.21 3 23 20 21 16 3.22 3 6 10 21 16 3.23 3 16 6 21 16 3.24 3 4 0 21 16 3.25 3 7 0 21 16 3.26 3 10 0 21 16 3.27 3 1 0 21 16 3.28 3 10 0 21 16 3.29 3 21 8 21 16 3.30 3 9 20 21 16 4.31 4 12 20 18 12 4.32 4 15 10 18 12 4.33 4 12 6 18 12 4.34 4 5 0 18 12 4.35 4 20 0 18 12 4.36 4 17 0 18 12 4.37 4 20 0 18 12 4.38 4 3 0 18 12 4.39 4 18 8 18 12 4.40 4 10 20 18 12 On Sun, Jul 15, 2012 at 12:32 PM, Santiago Guallar <sguallar at yahoo.com> wrote:> Hi, > > I have a dataset which contains several time records for a number of days, plus a variable (light) that allows to determine night time (lihgt= 0) and daytime (light> 0). I need to obtain get dusk time and dawn time for each day and place them in two columns. > > This is the starting point (d): > day time light > 1 1 20 > 1 12 10 > 1 11 6 > 1 9 0 > 1 6 0 > 1 12 0 > ... > 30 8 0 > 30 3 0 > 30 8 0 > 30 3 0 > 30 8 8 > 30 9 20 > > > And this what I want to get: > day time light dusk dawn > 1 1 20 11 10 > 1 12 10 11 10 > 1 11 6 11 10 > 1 9 0 11 10 > 1 6 0 11 10 > 1 12 0 11 10 > ... > 30 8 0 9 5 > 30 3 0 9 5 > 30 8 0 9 5 > 30 3 0 9 5 > 30 8 8 9 5 > 30 9 20 9 5 > > This is the code for data frame d: > day= rep(1:30, each=10) > n= length(dia); x= c(1:24) > time= sample(x, 300, replace= T) > light= rep(c(20,10,6,0,0,0,0,0,8,20), 30) > d=data.frame(day,time,light) > > I'd need to impose a double condition like the next but if does not take more than one: > attach(d) > for (i in 1: n){ > if (light[i-1]>2 & light[i]<2){ > d$dusk<- time[i-1] > } > if (light[i-1]<2 & light[i]>2){ > d$dawn<- time[i] > } > } > detach(d) > d > > Thank you for your help > [[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. >-- Jim Holtman Data Munger Guru What is the problem that you are trying to solve? Tell me what you want to do, not how you want to do it.
Hello, My code couldn't find the right input columns because your real data has different names, it could only find the example dataset's names. And there's another problem, my code would give correct answers with a limted number of possible inputs and fail with real data. Corrected: f <- function(x){ zrle <- rle(x$lig == 0) if(zrle$values[1]){ idusk <- sum(zrle$lengths[1:2]) + 1 idawn <- zrle$lengths[1] + 1 x$dusk <- x$dtime[ idusk ] x$dawn <- x$dtime[ idawn ] }else{ idusk <- zrle$lengths[1] + 1 x$dusk <- x$dtime[ idusk ] x$dawn <- NA } x } do.call(rbind, by(d, d$date, f)) One more thing, you are reading your dataset into a data.frame forgetting that character strings become factors. Try str(d) to see it. ('d' is the data.frame.) You could/should coerce the date/time values to appropriate classes, something like d$time <- as.character(d$time) d$time <- as.POSIXct(d$time, format="%d/%m/%y %H:%M:%S") d$date <- as.character(d$date) d$date <- as.Date(d$date, format="%d/%m/%y") Hope this helps, Rui Barradas Em 17-07-2012 07:14, Santiago Guallar escreveu:> Thank you Rui, > > When applied to my original data, your code goes through although it > does not produce the correct results: for dusk gives the first time > value of next day, for dawn it gives NA. It seems that the function f > doesn't find the right input columns. > A, Ilso had to push up the memory size. > Attached a file (containing just 3000 of the original c. 45000 rows) > after dput(). > > Santi > > > ------------------------------------------------------------------------ > *From:* Rui Barradas <ruipbarradas at sapo.pt> > *To:* Santiago Guallar <sguallar at yahoo.com> > *Cc:* r-help at r-project.org > *Sent:* Sunday, July 15, 2012 7:21 PM > *Subject:* Re: [R] Imposing more than one condition to if > > Hello, > > There are obvious bugs in your code, you are testing for light > 2 or > ligth < 2 but this would mean that dusk and dawn are undetermined for > light == 2 and that they happen at light == 1. > > Without loops or compound logical conditions: > > > f <- function(x){ > x$dawn <- x$time[ which.min(x$light) ] > x$dusk <- x$time[ max(which(x$light == 0)) + 1 ] > x > } > > do.call(rbind, by(d, d$day, f)) > > Hope this helps, > > Rui Barradas > > Em 15-07-2012 17:32, Santiago Guallar escreveu: > > Hi, > > > > I have a dataset which contains several time records for a number > of days, plus a variable (light) that allows to determine night time > (lihgt= 0) and daytime (light> 0). I need to obtain get dusk time > and dawn time for each day and place them in two columns. > > > > This is the starting point (d): > > day time light > > 1 1 20 > > 1 12 10 > > 1 11 6 > > 1 9 0 > > 1 6 0 > > 1 12 0 > > ... > > 30 8 0 > > 30 3 0 > > 30 8 0 > > 30 3 0 > > 30 8 8 > > 30 9 20 > > > > > > And this what I want to get: > > day time light dusk dawn > > 1 1 20 11 10 > > 1 12 10 11 10 > > 1 11 6 11 10 > > 1 9 0 11 10 > > 1 6 0 11 10 > > 1 12 0 11 10 > > ... > > 30 8 0 9 5 > > 30 3 0 9 5 > > 30 8 0 9 5 > > 30 3 0 9 5 > > 30 8 8 9 5 > > 30 9 20 9 5 > > > > This is the code for data frame d: > > day= rep(1:30, each=10) > > n= length(dia); x= c(1:24) > > time= sample(x, 300, replace= T) > > light= rep(c(20,10,6,0,0,0,0,0,8,20), 30) > > d=data.frame(day,time,light) > > > > I'd need to impose a double condition like the next but if does > not take more than one: > > attach(d) > > for (i in 1: n){ > > if (light[i-1]>2 & light[i]<2){ > > d$dusk<- time[i-1] > > } > > if (light[i-1]<2 & light[i]>2){ > > d$dawn<- time[i] > > } > > } > > detach(d) > > d > > > > Thank you for your help > > [[alternative HTML version deleted]] > > > > > > > > ______________________________________________ > > R-help at r-project.org <mailto: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. > > > > >