Nice! It works. Thank you, Rui
There's something that takes me back to the original question, though.
The code takes the first value that meets the critical condition (light
==0); however, this value can appear more than once a day because these
animals nest in dark caves, and once they are in the logger sensor
registers a 0. So, a second condition limiting the time at which the
critical condition can be accepted to calculate dusk should be
implemented; something like (although R doesn't allow to impose the
double condition):
if (05:00:00<z$clock> 17:00:00) {zrle <- rle(x$lig == 0)}
Santi
*From:* Rui Barradas <ruipbarradas at sapo.pt>
*To:* Santiago Guallar <sguallar at yahoo.com>
*Cc:* r-help at r-project.org
*Sent:* Wednesday, July 18, 2012 11:37 AM
*Subject:* Re: [R] Imposing more than one condition to if
hELLO,
There was no nedd to change the names of the variables inside the
fucntion. What was going on s that in this new file column 'dtime'
doesn't exist. Since column 'clock' exists in all files, I've changed
the function once again, making it more general.
Note that there is an argument 'colTime' with a default value. In the
function's use below I call it with and without that argument.
f <- function(x, colTime="clock"){
zrle <- rle(x$lig == 0)
if(zrle$values[1]){
idusk <- sum(zrle$lengths[1:2]) + 1
idawn <- zrle$lengths[1] + 1
x$dusk <- x[ idusk , colTime ]
x$dawn <- x[ idawn , colTime ]
}else{
idusk <- zrle$lengths[1] + 1
x$dusk <- x[ idusk , colTime ]
x$dawn <- NA
}
x
}
str(d)
#d$date <- as.Date(d$date, format="%d/%m%/y")
#library(chron)
#tm <- times(as.character(d$clock))
#d$clock <- tm
# See what will happen. This call uses the default 'colTime'
bb <- by(d, d$date, f)
for(i in seq_along(bb)) print(head(bb[[i]], 1))
# call and rbind. This call uses explicit arg 'colTime'
do.call(rbind, by(d, d$date, f, colTime="clock"))
# Alternatively, it could be, because 'bb' is already created,
do.call(rbind, bb)
In the code above, I use an optional conversion to date and time
classes; as.Date is part of base R, but class times needs package
chron.
It's a good idea to convert these variables, you can later use, say,
arithmetics on dates and times, such as differences.
Hope this helps,
Rui Barradas
Em 17-07-2012 19:53, Santiago Guallar escreveu:
> Thank for your time, Rui.
> Now, I get this error message:
> Error en rbind(deparse.level, ...) :
> numbers of columns of arguments do not match
> Apparently, some columns have missing values and rbind doesn't
> tried:
> require(plyr)
> do.call(rbind.fill, by(z, z$date, f))
> Then the code runs through but dusk the variable dusk is missing and
> dawn is filled with NA.
> Just in case the problem simply lies in a name, this is your code
> I changed the object names (basically 'x' and 'd' by 'z') to
> to the names of my dataset:
> f <- function(z){
> zrle <- rle(z$lig == 0)
> if(zrle$values[1]){
> idusk <- sum(zrle$lengths[1:2]) + 1
> idawn <- zrle$lengths[1] + 1
> z$dusk <- z$dtime[ idusk ]
> z$dawn <- z$dtime[ idawn ]
> }else{
> idusk <- zrle$lengths[1] + 1
> z$dusk <- z$dtime[ idusk ]
> z$dawn <- NA
> }
> z
> }
>
> do.call(rbind, by(z, z$date, f))
> Again, I attached a dput() with the object z which contains my
> Santi
>
> *From:* Rui Barradas <ruipbarradas at sapo.pt
<mailto:ruipbarradas at sapo.pt>>
> *To:* Santiago Guallar <sguallar at yahoo.com
<mailto:sguallar at yahoo.com>>
> *Cc:* r-help at r-project.org <mailto:r-help at r-project.org>
> *Sent:* Tuesday, July 17, 2012 11:52 AM
> *Subject:* Re: [R] Imposing more than one condition to if
>
>
> Hello,
>
> My code couldn't find the right input columns because your
> data has
> different names, it could only find the example dataset's
>
> And there's another problem, my code would give correct
> 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
> 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
> > does not produce the correct results: for dusk gives the
> > value of next day, for dawn it gives NA. It seems that the
> > 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.
> > after dput().
> >
> > Santi
> >
> >
> >
------------------------------------------------------------------------
> > *From:* Rui Barradas <ruipbarradas at sapo.pt
<mailto:ruipbarradas at sapo.pt>
> <mailto:ruipbarradas at sapo.pt <mailto:ruipbarradas at sapo.pt>>>
> > *To:* Santiago Guallar <sguallar at yahoo.com
<mailto:sguallar at yahoo.com>
> <mailto:sguallar at yahoo.com <mailto:sguallar at yahoo.com>>>
> > *Cc:* r-help at r-project.org
<mailto:r-help at r-project.org> <mailto:r-help at r-project.org
<mailto:r-help at r-project.org>>
> > *Sent:* Sunday, July 15, 2012 7:21 PM
> > *Subject:* Re: [R] Imposing more than one condition
> >
> > Hello,
> >
> > There are obvious bugs in your code, you are
> > ligth < 2 but this would mean that dusk and dawn are
> > 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
> > of days, plus a variable (light) that allows to
> > (lihgt= 0) and daytime (light> 0). I need to obtain get
> > and dawn time for each day and place them in two
> > >
> > > 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
> > 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> <mailto:R-help at r-project.org
<mailto:R-help at r-project.org>>
> <mailto:R-help at r-project.org <mailto:R-help at r-project.org>
<mailto:R-help at r-project.org <mailto:R-help at r-project.org>>>