1

The following is part of my R script:

for (i in 1:N-1) {
  if (-50<nw.bank[i] && 50>nw.bank[i]) {
      rl[i+1] <- (rl[i]+0.001)
  } 
    else {
      rl[i+1] <- rl[i]
  }
}

When run, I get the following message:

"Error in if (-50 < nw.bank[i] && 50 > nw.bank[i]) { : 
  missing value where TRUE/FALSE needed"

Can anyone help me out? Thank you so much!

best, hyun

Hong Ooi
  • 56,353
  • 13
  • 134
  • 187
ppp
  • 113
  • 1
  • 1
  • 7
  • 2
    I don't know R but try with enclosing each expression in paranthesis :`((-50 < nw.bank[i]) && (50 > nw.bank[i]))` , Probably ! – AllTooSir Jul 03 '13 at 05:28
  • You'll get an error if `nw.bank[i]` is `NA`. – Andy Clifton Jul 03 '13 at 05:32
  • Hi LostBrit, yeah, you are right. If I run the if statement with Ctrl+R, i.e. (-50nw.bank[i]), I get the result as: [1] NA. This is strange because nw.bank is well defined and separately running nw.bank gives a correct result. Do you know what is wrong? I really appreciate for your help! – ppp Jul 03 '13 at 06:50

3 Answers3

5

Note that 1:N-1 is parsed as (1:N) - 1. This means your loop is iterating over 0, 1, 2, ... (N - 1), and the test using nw.bank[i] will error out on the first iteration. You probably meant 1:(N - 1).

Hong Ooi
  • 56,353
  • 13
  • 134
  • 187
  • Hi Hong, I really appreciate for your comment. It helped. But there seems to be a problem elsewhere as well. If I run the if statement with Ctrl+R, i.e. (-50nw.bank[i]), I get the result as: [1] NA. This is strange because nw.bank is well defined and separately running nw.bank gives a correct result. Do you know what is wrong? Thank you for your help! – ppp Jul 03 '13 at 06:55
0

R for loops run slower when compared to code that handles vectors directly.

This procedure you give can be vectorized as follows:

Get some random values for nw.bank so the calculation can be demonstrated:

nw.bank<- 200*runif(20)-100 

[1]  43.273799  19.051499  37.552510  76.940632 -59.176684 -27.379326
[7] -37.512520  77.776610  88.127792 -91.213580 -50.691943  78.697820
[13]  36.933503 -76.973450  28.143336 -55.136574 -70.693362 -14.213375
[19]  15.666707  -3.072321

Note there is only one ampersand (&) in a vectorized AND

as.numeric(((-50<nw.bank) & (50>nw.bank)))
   [1] 1 1 1 0 0 1 1 0 0 0 0 0 1 0 1 0 0 1 1 1

Now multiply by 0.001 and take cumulative sum

   cumsum(0.001*as.numeric(((-50<nw.bank) & (50>nw.bank))))

[1] 0.001 0.002 0.003 0.003 0.003 0.004 0.005 0.005 0.005 0.005 0.005 0.005
[13] 0.006 0.006 0.007 0.007 0.007 0.008 0.009 0.010

Now you need an adjustable initial value, perhaps, and you are done

rlinit <- 3.0; 
rl <- cumsum(0.001*as.numeric(((-50<nw.bank) & (50>nw.bank)))) + rlinit



[1] 3.001 3.002 3.003 3.003 3.003 3.004 3.005 3.005 3.005 3.005 3.005 3.005
[13] 3.006 3.006 3.007 3.007 3.007 3.008 3.009 3.010
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
Paul
  • 26,170
  • 12
  • 85
  • 119
  • Hi Paul, Thank you so much! But is this the only solution? If I can find and fix any logical error with my scripts I would like to go with a simpler approach since I have some more parts in my script that are similiar to the one I posted. best, hyun – ppp Jul 03 '13 at 07:13
  • There are multiple ways to do it. Use what works for you. I would argue that 2 lines are simpler than 8, it is easy to read and R will run it faster, but it also takes longer for a programmer to write and requires knowing a lot of R functions. – Paul Jul 03 '13 at 07:29
  • Got it! I'll try that out. I really appreciate for your help! – ppp Jul 03 '13 at 07:34
0

If it's not the problem with 1:N-1 as Hong suggested, then try to find if there is NA in nw.bank using any(is.na(nw.bank)), and use & instead of && unless you have a good reason (see R - boolean operators && and ||).

Community
  • 1
  • 1
cogitovita
  • 1,685
  • 1
  • 15
  • 15
  • Hi Cogitovita, I tried is.na and yes there are many NAs. But, the number of NA are different between the result from is.na and running nw.bank separately. Anyway, I cannot figure out why I am getting NAs. Could you help me out please? I really appreciate :) – ppp Jul 03 '13 at 07:20
  • For counting the number of `NA`s, I recommend to use `sum(is.na(nw.bank))`. The `NA`s may be introduced by unstream analysis. – cogitovita Jul 03 '13 at 07:33
  • I see.. Could you please tell me what you mean by 'unstream analysis'? I really appreciate! – ppp Jul 03 '13 at 07:44
  • How do you get `nw.bank`? Do you expect that it may contain `NA`? If not, you should inspect the code that generates `nw.bank` and see what happenes there. – cogitovita Jul 03 '13 at 08:19