Reputation: 2534
This is related to a previous question at R: How to include NA in ifelse?. I am trying to create a column ID
based on logical tests using values from a number of different columns. For the following example dataframe:
test2 <- structure(list(time1 = c(10L, 20L, NA, NA), time2 = c(5L, NA,
10L, NA), size = 1:4, type = structure(1:4, .Label = c("A", "B",
"C", "D"), class = "factor"), ID = c("6", "6", NA, NA)), .Names = c("time1",
"time2", "size", "type", "ID"), row.names = c(NA, -4L), class = "data.frame")
which looks like
time1 time2 size type
1 10 5 1 A
2 20 NA 2 B
3 NA 10 3 C
4 NA NA 4 D
I want to create a column ID
containing a value of 6 when the following conditions are met: 1) either time1
or time2
is not NA, 2) size
is greater or equal to 2, and 3) type
is not equal to C or D. I have been trying the following code:
test2$ID <- ifelse(is.na(test2$time1) & is.na(test2$time2) & test2$size >= 2 | test2$type %in% "C" | test2$type %in% "D", NA, "6")
For some reason, the "greater than or equal to 2" statement is not working properly. This code gives me the solution
time1 time2 size type ID
1 10 5 1 A 6
2 20 NA 2 B 6
3 NA 10 3 C NA
4 NA NA 4 D NA
However, the solution I need should be
time1 time2 size type ID
1 10 5 1 A NA
2 20 NA 2 B 6
3 NA 10 3 C NA
4 NA NA 4 D NA
Can anyone tell me what I am doing wrong?
Also: I am having a hard time understanding how logical operators work in R. It seems these are evaluated sequentially, so that X & Y | Z is not equivalent to Z | X & Y. Is this correct? Could I make a statement link (X & Y) | Z and this would be equivalent to Z | (X & Y)? Sorry for the silly question!
Upvotes: 0
Views: 281
Reputation: 32426
test2$ID <- with(test2, ifelse( (!is.na(time1) | !is.na(time2)) &
size >= 2 &
!type %in% c("C", "D"), 6, NA))
Yes like you said you can use parentheses to force &
to evaluate before |
.
Upvotes: 4