1

I have a following R code. I wonder what is the difference when I put mat<-matrix(1:20, ncol=5) outside the function. I am getting same results in both cases.

fun<-function(x,y){
  mat<-matrix(1:20, ncol=5)
  for (i in 1:x){
    for (j in 1:y){
      mat[i,j]=rnorm(1)
      return(mat)
    }
  }
}
fun(4,5)

The following code works as suggested in the comments and answer. Why it does not work when converted to a function as above?

mat<-matrix(1:20, ncol=5)
for(i in 1:4){
  for (j in 1:5){
   mat[i,j]=rnorm(1)
  }
}
mat
Alph
  • 391
  • 2
  • 7
  • 18
  • 2
    What is the point of this double for loop? What is your function doing? Why can't you just do `mat[] <- rnorm(length(mat))`? – David Arenburg Jul 13 '15 at 20:04
  • 1
    And there are scoping issues with your `mat` assignment. See http://stackoverflow.com/questions/20766649/understanding-lexical-scoping-in-r. It exists as an object within the function, but you are trying to assign it to `A` outside of the function. – Pierre L Jul 13 '15 at 20:07
  • @ David Arenburg. This is for self-study. – Alph Jul 13 '15 at 20:18
  • 2
    Better to study doing it the right way. – Pierre L Jul 13 '15 at 20:19
  • 1
    As @DavidArenburg says, you can vectorize with `rnorm(length(mat))` so you totally don't need the double-loop. You might as well learn to write clear scalable R from the start. – smci Jul 13 '15 at 21:04

1 Answers1

1
fun1 <- function(x,y) {
  mat <- matrix(1:20, ncol=5)
  mat[1:x, 1:y] <- rnorm(x*y)
  mat
}

This will achieve your goal of creating a function that accepts indices as two arguments and returns a matrix with random normally distributed numbers by the index.

fun1(2,1)
#           [,1] [,2] [,3] [,4] [,5]
#[1,] -0.2883407    5    9   13   17
#[2,] -0.5290704    6   10   14   18
#[3,]  3.0000000    7   11   15   19
#[4,]  4.0000000    8   12   16   20

Note that the last line is returned when the function is called.

The mat matrix created in the function is not available in the Global environment:

mat
#Error: object 'mat' not found

Whenever you write a nested for loop as a new user of R, alarm bells should go off. There is usually a better way. The advantage of the nested loop is that it "makes sense." But the clear logical progression turns out to be very inefficient in execution. There are exceptions of course, but you will most likely not run into them any time soon. It is better to take the time to learn R's programming intuition.

There are many discussions of scoping for study:

  1. R environments and function call stacks

  2. Scoping and functions in R 2.11.1 : What's going wrong?

  3. http://developer.r-project.org/nonstandard-eval.pdf

  4. http://adv-r.had.co.nz/Functions.html#lexical-scoping

Community
  • 1
  • 1
Pierre L
  • 28,203
  • 6
  • 47
  • 69