Skip to content

Imposing more than one condition to if

7 messages · Santiago Guallar, Rui Barradas

#
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 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 work. I 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?after I changed the object names?(basically 'x' and?'d' by 'z') to adapt them 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 dataset.
?
Santi

From: Rui Barradas <ruipbarradas at sapo.pt>
#
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 work. I 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 after I changed the object names (basically 'x' and 'd' by 'z') to adapt them 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 dataset.
?
Santi

From: Rui Barradas <ruipbarradas at sapo.pt>
#
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:
#
Hello,

You're right. I had thought of this, and I believe there's a day when it 
happens to have a zero in the middle of the day. R doesn't allow 
conditions like the one you've written but it does allow multiple 
conditions, combined using the logical connectives, 'not' - '!', 'or' - 
'|' and 'and' - '&'. Let's see:

Day <- 05:00:00 <= x$clock & x$clock <= 17:00:00
Night <- !(05:00:00 <= x$clock & x$clock <= 17:00:00) # equal to:
Night <- x$clock < 05:00:00 | x$clock > 17:00:00

So, you had the first condition reversed and maybe !Day is more readable ;)

(Note: to check if a variable is in an interval, say (a, b), I find it 
better to write a < x & x < b with the interval's end points as 
condition extremes, like Day above. Then if negation is needed half the 
work is already done.)

Anyway, it should be easy to put the compound condition in the function f().

Rui Barradas

Em 18-07-2012 19:02, Santiago Guallar escreveu: