user288609
user288609

Reputation: 13035

parameter passing mechanism in R

The following function is used to multiply a sequence 1:x by y

f1<-function(x,y){return (lapply(1:x, function(a,b) b*a, b=y))}

Looks like a is used to represent the element in the sequence 1:x, but I do not know how to understand this parameter passing mechanism. In other OO languages, like Java or C++, there have call by reference or call by value.

Upvotes: 3

Views: 653

Answers (4)

agstudy
agstudy

Reputation: 121598

You should read the help of lapply to understand how it works. Read this excellent answer to get and a good explanation of different xxpply family functions.

From the help of laapply:

lapply(X, FUN, ...) 

Here FUN is applied to each elementof X and ... refer to:

... optional arguments to FUN.

Since FUN has an optional argument b, We replace the ... by , b=y.

You can see it as a syntax sugar and to emphasize the fact that argument b is optional comparing to argument a. If the 2 arguments are symmetric maybe it is better to use mapply.

Upvotes: 1

Scott Ritchie
Scott Ritchie

Reputation: 10543

Short answer: R is call by value. Long answer: it can do both.

Call By Value, Lazy Evaluation, and Scoping

You'll want to read through: the R language definition for more details.

R mostly uses call by value but this is complicated by its lazy evaluation:

So you can have a function:

f <- function(x, y) {
   x * 3
}

If you pass in two big matrixes to x and y, only x will be copied into the callee environment of f, because y is never used.

But you can also access variables in parent environments of f:

y <- 5
f <- function(x) {
   x * y
}
f(3) # 15

Or even:

y <- 5
f <- function() {
  x <- 3
  g <- function() {
    x * y
  }
}
f() # returns function g()
f()() # returns 15

Call By Reference

There are two ways for doing call by reference in R that I know of.

One is by using Reference Classes, one of the three object oriented paradigms of R (see also: Advanced R programming: Object Oriented Field Guide)

The other is to use the bigmemory and bigmatrix packages (see The bigmemory project). This allows you to create matrices in memory (underlying data is stored in C), returning a pointer to the R session. This allows you to do fun things like accessing the same matrix from multiple R sessions.

Upvotes: 4

Fernando
Fernando

Reputation: 7905

To multiply a vector x by a constant y just do

x * y

The (some prefix)apply functions works very similar to each other, you want to map a function to every element of your vector, list, matrix and so on:

x = 1:10
x.squared = sapply(x, function(elem)elem * elem)
print(x.squared)
[1]   1   4   9  16  25  36  49  64  81 100

It gets better with matrices and data frames because you can now apply a function over all rows or columns, and collect the output. Like this:

m = matrix(1:9, ncol = 3)
# The 1 below means apply over rows, 2 would mean apply over cols
row.sums = apply(m, 1, function(some.row) sum(some.row))
print(row.sums)
[1] 12 15 18

Upvotes: 2

josliber
josliber

Reputation: 44330

If you're looking for a simple way to multiply a sequence by a constant, definitely use @Fernando's answer or something similar. I'm assuming you're just trying to determine how parameters are being passed in this code.

lapply calls its second argument (in your case function(a, b) b*a) with each of the values of its first argument 1, 2, ..., x. Those values will be passed as the first parameter to the second argument (so, in your case, they will be argument a).

Any additional parameters to lapply after the first two, in your case b=y, are passed to the function by name. So if you called your inner function fxn, then your invocation of lapply is making calls like fxn(1, b=4), fxn(2, b=4), .... The parameters are passed by value.

Upvotes: 1

Related Questions