R中的参数传递机制

时间:2014-01-08 02:49:34

标签: r

以下函数用于将序列1:x乘以y

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

看起来a用于表示序列1:x中的元素,但我不知道如何理解这个参数传递机制。在其他OO语言中,如Java或C ++,有call by referencecall by value

4 个答案:

答案 0 :(得分:3)

简短回答:Rcall by value。答案很长:它可以做到这两点。

按值调用,延迟评估和范围确定

您需要阅读:the R language definition了解更多详情。

R主要使用call by value,但由于其懒惰的评估而变得复杂:

所以你可以有一个功能:

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

如果您将两个大矩阵传递给xy,则只有x会被复制到f的被调用者环境中,因为y是从未使用过。

但您也可以在f

的父环境中访问变量
y <- 5
f <- function(x) {
   x * y
}
f(3) # 15

甚至:

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

按参考呼叫

我知道有两种方法可以在R中执行call by reference

一个是使用Reference Classes,R的三个面向对象范例之一(另见:Advanced R programming: Object Oriented Field Guide

另一种方法是使用bigmemorybigmatrix个包(请参阅The bigmemory project)。这允许您在内存中创建矩阵(底层数据存储在C中),返回指向R会话的指针。这允许您做一些有趣的事情,比如从多个R会话访问相同的矩阵。

答案 1 :(得分:2)

要将向量x乘以常数y,只需执行

x * y

(某些前缀)apply 函数的工作方式非常相似,您希望将函数映射到向量,列表,矩阵等的每个元素:

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

矩阵和数据帧会变得更好,因为您现在可以在所有行或列上应用函数,并收集输出。像这样:

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

答案 2 :(得分:1)

如果您正在寻找一种简单的方法来将序列乘以常数,请务必使用@ Fernando的答案或类似的东西。我假设您只是想确定如何在此代码中传递参数。

lapply使用其第一个参数function(a, b) b*a的每个值调用其第二个参数(在您的情况下为1, 2, ..., x)。这些值将作为第一个参数传递给第二个参数(因此,在您的情况下,它们将是参数a)。

前两个lapply之后的任何其他参数(在您的情况b=y中)将按名称传递给函数。因此,如果您调用了内部函数fxn,则调用lapply会调用fxn(1, b=4), fxn(2, b=4), ...之类的调用。参数按值传递。

答案 3 :(得分:1)

您应该阅读lapply的帮助以了解其工作原理。阅读这篇优秀的answer以获得不同xxpply系列函数的详细解释。

laapply的帮助下:

lapply(X, FUN, ...) 

这里FUN应用于X的每个元素,并且......参考:

  

... FUN的可选参数。

由于FUN有一个可选参数b,我们将...替换为b = y。

您可以将其视为语法糖,并强调参数b与参数a相比是可选的这一事实。如果2个参数是对称的,那么最好使用mapply