1

I'm new to R and I'm trying to understand how loops work in R. But I just can't figure out how to make them work when there are 2 (or more) of them.

Here is the code:

 for (i in 1:(length(b)-1))
{
  for (j in 1:(length(a))
  {
    if ((a[j] >= b[i]) && (a[j] <b[i+1]))
    {
      1
    }
    else
    {
      0
    }
  }
}

a and b are two vectors.

So (in case the code is not clear - which is certainly the case) all i want is that the condition tests for i=1 then goes through all j's. Then tests for i=2 and goes through all j's. Etc. And when the condition is ok, returns 1, otherwise 0.

All i want is an output with a matrix/vector of 0's and 1's. 1 when the condition is respected, 0 when it isn't. About the inputs, "a" could be (0,0.01,0.02,...,0.99) and "b" could be (0,0.1,0.2,...,1). If you find/know a way without loops, that would be great too.

Thank you for your help. Sorry if this has already been asked. I'm fairly new to this.

EDIT : @alexis_laz I didn't think about pre-allocating a matrix. That could do the trick. Thank you, a lot. However, when I try this function:

test <- function(a,b) 
{ 
  mat <- matrix(,length(a), (length(b)-1))
  for (i in 1:(length(b)-1))
  {
    for (j in 1:length(a))
    {
      if ((a[j] >= b[i]) && (a[j] <b[i+1])) 
      {
      mat[j,i] = 1
      }
      else 
      {
      mat[j,i] = 0
      }
    }
  }
}

Litteraly nothing happens (no errors, the matrix is not filling in, etc.). I tried it with 2 vectors (the same defined earlier). Is there something wrong with this function ? Something I don't understand ? (I'm really new to R, sorry if all my questions seem stupid or unclear.)

Ken Traf
  • 39
  • 3
  • 4
    How about making your example [reproducible](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) by adding some sample input and the corresponding desired output. Does it have to be done in loops? Often there are better ways in R. Also, loops don't return anything. They aren't a function, just a control structure. Where do you want this value to wind up? – MrFlick Oct 25 '15 at 18:16
  • @MrFlick _They aren't a function_ - are you sure about it? `is.function` seems to think that `for` is a function after all. – zero323 Oct 25 '15 at 18:38
  • @zero323 They aren't functions in the sense they don't return anything `a<-for(i in 1:5) {i}` leaves `a` as `NULL`. – MrFlick Oct 25 '15 at 18:40
  • Sadly it doesn't. No for comprehensions in R. Still it is quite interesting language property. – zero323 Oct 25 '15 at 18:49
  • 1
    @zero323 : Actually see 'typeof(`for`)' vs -e.g.- `typeof(typeof)`; `is.function` (and `mode`, too) returns TRUE (and "function", respectively) for either of these "typeof"s. I guess, in a stricter sense, we are used to "closure"s as "function"s – alexis_laz Oct 25 '15 at 18:55
  • Hi, a few minutes ago another user asked [a similar question](http://stackoverflow.com/a/33332724/1655567) but pertaining to the panel data. – Konrad Oct 25 '15 at 18:59
  • @alexis_laz That's a good point. Moreover `for` usage is much more restricted than a typical R function. – zero323 Oct 25 '15 at 19:07
  • @MrFlick `NULL` is a valid return value for a function. AFAIU, technically, `for` is a function in R. – Roland Oct 25 '15 at 19:07
  • Ok. `for` is a function that will only return `NULL`. So using it to return anything else (as the OP seems to be trying to do) would be a mistake. – MrFlick Oct 25 '15 at 19:11
  • @MrFlick All i want is an output with a matrix/vector of 0's and 1's. 1 when the condition is respected, 0 when it isn't. About the inputs, "a" could be (0,0.01,0.02,...,0.99) and "b" could be (0,0.1,0.2,...,1). Sorry if I'm not clear enough. EDIT: And no, of course, it does not have to be done in loops. If the mechanism can be achieved with another method, I'll be pleased to learn it. – Ken Traf Oct 26 '15 at 08:37
  • @KenTraf : You need to pre-allocate a structure to hold the results; e.g. `ans = matrix(, length(a), length(b) - 1)` and in the loop assign to the respective position: `ans[j, i] = 1`. I'm guessing that if you edit with sample "a", "b" and output, there, soon, will be an answer that avoids the loops, too. Perhaps, see `?outer`; you might need something like `outer(a, b[seq_len(length(b) - 1L)], ">=") & outer(a, b[-1], "<")` – alexis_laz Oct 26 '15 at 11:31
  • Great, that could really work, however something seems wrong. I edited my question. If you have the time, could you look at it ? Thank you for your time, really. – Ken Traf Oct 26 '15 at 12:08
  • Nevermind, I found what was wrong. Thank you for your time. Adding the answer. – Ken Traf Oct 26 '15 at 12:15
  • I assume you noticed you were not returning `mat` at the end of the function. – Molx Oct 26 '15 at 12:16
  • That was it, yeah! Thank you. – Ken Traf Oct 26 '15 at 12:20

1 Answers1

2

Thank you guys. I've found how to do it. Briefly : I needed to pre-allocate a matrix and then return it at the end of the function.

test <- function(a,b) 
{ 
  mat <- matrix(,length(a), (length(b)-1))
  for (i in 1:(length(b)-1))
  {
    for (j in 1:length(a))
    {
      if ((a[j] >= b[i]) && (a[j] <b[i+1])) 
      {
      mat[j,i] = 1
      }
      else 
      {
      mat[j,i] = 0
      }
    }
  }
  return(mat)
}

Thank you again.

Ken Traf
  • 39
  • 3
  • Remember, StackOverflow is not a webforum, so you shouldn't post edits to your question or additional information as an answer. Answers are reserved for just that: answers. Instead, edit your original question. – Thomas Oct 26 '15 at 12:03
  • Edited it. This is now the final answer. Thank you. – Ken Traf Oct 26 '15 at 12:24