0

A sample data:

t.mean <- c(15.02,8)
t.base <- 10
t.opt <- 28

dat <- data.frame(cbind(t.mean,t.base,t.opt))
dat

 t.mean t.base t.opt
1  15.02     10    28
2   8.00     10    28

I want to create another column in dat called fT. The condition is that if t.mean >= t.base and t.mean <= t.opt, fT is calculated as (t.mean - t.base)/(t.opt - t.base) . If not, than assign a value of 0.

In this case, the second row does not meet the condition (t.mean >= t.base), therefore the value of fT should be zero. Here's my code:

if(dat$t.mean >= dat$t.base & dat$t.mean <= dat$t.opt){
   dat$fT <- (dat$t.mean - dat$t.base)/(dat$t.opt - dat$t.base)
} else {
   dat$fT <- 0
}

dat

 t.mean t.base t.opt         fT
1  15.02     10    28  0.2788889
2   8.00     10    28 -0.1111111

I am not sure why is this is happening? In addition, it also generates an error

 In if (dat$t.mean >= dat$t.base & dat$t.mean <= dat$t.opt) { :
   the condition has length > 1 and only the first element will be used

On the contrary, if I use an ifelse statement, it gives me the right answer.

 ifelse(dat$t.mean >= dat$t.base & dat$t.mean <= dat$t.opt, dat$fT <- (dat$t.mean - dat$t.base)/(dat$t.opt - dat$t.base),0)

[1] 0.2788889 0.0000000

just wondering what do I need to to fix my first code?

Thanks

89_Simple
  • 3,393
  • 3
  • 39
  • 94
  • Use `ifelse` instead of `if/else` . The `if/else` is done for a single element instead of vectors with lengths greater than 1 – akrun Dec 11 '17 at 17:39
  • I have used it. I just wondered what can be done to correct the if/else statement. Thank you. – 89_Simple Dec 11 '17 at 17:42
  • `ifelse` is vectorized, expects a vector of conditions, gives a vector of results. `if` is not vectorized, as the warning says, "the condition has length > 1 and only the first element will be used". It only looks at the first condition in your vector of conditions. – Gregor Thomas Dec 11 '17 at 17:42
  • So that means I cannot use the `if/else` for my purpose? I must use `ifelse`? – 89_Simple Dec 11 '17 at 17:43
  • Yes. You *could* use `if/else` inside a `for` loop, but it would be very inefficient. It is much better to use `ifelse`. – Gregor Thomas Dec 11 '17 at 17:44
  • `ifelse` will actually return a result, the better way to use it is `dat$fT = with(dat, ifelse(t.mean >= t.base & t.mean <= t.opt, (t.mean - t.base) / (t.opt - t.base), 0))`. The `with` saves you from needing to type `dat$` every time, but the main point is to have the assignment `<-` *outside* the `ifelse`. – Gregor Thomas Dec 11 '17 at 17:59

0 Answers0