以下函数用于将序列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 reference
或call by value
。
答案 0 :(得分:3)
简短回答:R
为call by value
。答案很长:它可以做到这两点。
您需要阅读:the R language definition了解更多详情。
R
主要使用call by value
,但由于其懒惰的评估而变得复杂:
所以你可以有一个功能:
f <- function(x, y) {
x * 3
}
如果您将两个大矩阵传递给x
和y
,则只有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)
另一种方法是使用bigmemory
和bigmatrix
个包(请参阅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
。