Reputation: 21
everyone.
Hopefully an easy syntax question. I'm trying to create a new variable in a table in R which would say "1" if my patient was in the age range I was looking at, or "0" for no. The age range I'm interested is between 2-155. The code is running without any errors, but it is not working. When I look in my table, the new variable will say 1 even though the age4 is 158 Here is what I have:
table$newvar <- if (table$age4>=2 && table$age4 <=155) {table$newvar=1} else {table$newvar=0}
Any help is appreciated! Thanks in advance!
Upvotes: 1
Views: 27258
Reputation: 35314
Two changes should be made:
ifelse()
function to generate the new column data.&
logical-AND operator when combining the results of the comparisons.table <- data.frame(age4=seq(1,200,10));
table$newvar <- ifelse(table$age4>=2 & table$age4<=155,1,0);
table;
## age4 newvar
## 1 1 0
## 2 11 1
## 3 21 1
## 4 31 1
## 5 41 1
## 6 51 1
## 7 61 1
## 8 71 1
## 9 81 1
## 10 91 1
## 11 101 1
## 12 111 1
## 13 121 1
## 14 131 1
## 15 141 1
## 16 151 1
## 17 161 0
## 18 171 0
## 19 181 0
## 20 191 0
The reason your code is not working is because the if
statement and the &&
operator are not vectorized. The &&
operator only examines the first element of each operand vector, and only returns a one-element vector representing the result of the logical-AND on those two input values. The if
statement always expects a one-element vector for its conditional, and executes the if-branch if that element is true, or the else-branch if false.
If you use a multiple-element vector as the conditional in the if
statement, you get a warning:
if (c(T,F)) 1 else 0;
## [1] 1
## Warning message:
## In if (c(T, F)) 1 else 0 :
## the condition has length > 1 and only the first element will be used
But for some odd reason, you don't get a warning if you use a multiple-element vector as an operand to &&
(or ||
):
c(T,F) && c(T,F);
## [1] TRUE
That's why your code appeared to succeed (by which I mean it didn't print any warning message), but it didn't actually do what was intended.
Upvotes: 5
Reputation: 269471
When used in arithmetic TRUE
and FALSE
become 1
and 0
so:
transform(table, newvar = (age4 >= 2) * (age4 <= 155) )
These also work:
transform(table, newvar = as.numeric( (age4 >= 2) & (age4 <= 155) ) )
transform(table, newvar = ( (age4 >= 2) & (age4 <= 155) ) + 0 )
transform(table, newvar = ifelse( (age4 >= 2) & (age4 <= 155), 1, 0) )
transform(table, newvar = (age4 %in% 2:155) + 0) # assuming no fractional ages
Upvotes: 0