简体   繁体   English

R:在apply系列函数中使用MoreArgs参数

[英]R: Using the MoreArgs argument in the apply family of functions

I have a complicated function that takes a bunch of graphical objects and ggplot maps and combines them into gtables. 我有一个复杂的函数,需要一堆图形对象和ggplot映射,并将它们组合成gtable。 For purpose of this question, I have represented that function as a simple linear function, MyFun1 or MyFun2, which differ only by the presence of a ... argument. 出于这个问题的目的,我将该函数表示为简单的线性函数MyFun1或MyFun2,它们的区别仅在于...参数的存在。

The function creating the gtables have two two arguments that vary and a bunch of other arguments that are constant in a given run. 创建gtable的函数具有两个变化的自变量和一堆在给定运行中恒定的其他自变量。 I am trying to run that function with mapply, using the MoreArgs argument to supply the constant (for each run -- changed in a bigger loop) arguments. 我正在尝试使用mapply运行该函数,使用MoreArgs参数提供常量(每次运行-在更大的循环中更改)的参数。 However, I got an error saying the passed values were surplusage, though they were used in the body. 但是,我出错了,尽管传递的值已在主体中使用,但它们还是多余的。

mArgs  <- list(y1=1, y2=2)
MyFun1  <- function(x, y){x*y1 + y*y2}
MyFun2 <- function(x, y, ...){x*y1 + y*y2}

R1 <- function(A, B){
   out <- mapply(MyFun, x=A, y=B, MoreArgs = mArgs)
} 
R1(1:3, 4:6)
 Error in (function (x, y)  : unused arguments (y1 = 1, y2 = 2)

Traceback: 追溯:

3. (function (x, y) 
{
    x * y1 + y * y2
})(x = dots[[1L]][[1L]], y = dots[[2L]][[1L]], y1 = 1, y2 = 2) 
2. mapply(MyFun, x = A, y = B, MoreArgs = mArgs) 
1. R1(1:3, 4:6) 

I thought perhaps the problem was that MyFun1 lacked the requisite formals to pass the additional arguments into the body, so I tried adding a ... argument. 我以为问题可能出在MyFun1缺少将附加参数传递到主体中所需的形式,所以我尝试添加一个...参数。 But now MyFun could not find the arguments in the MoreArgs list. 但是现在MyFun在MoreArgs列表中找不到参数。

R2 <- function(A, B){
   out <- mapply(MyFun2, x=A, y=B, MoreArgs = mArgs)
}
R2(1:3, 4:6)
 Error in (function (x, y, ...)  : object 'y1' not found 

Traceback: 追溯:

3. (function (x, y, ...) 
{
    x * y1 + y * y2
})(x = dots[[1L]][[1L]], y = dots[[2L]][[1L]], y1 = 1, y2 = 2) 
2. mapply(MyFun2, x = A, y = B, MoreArgs = mArgs) 
1. R2(1:3, 4:6) 

Then I thought, perhaps mArgs in the global environment was not in the scope of MyFun2, though it it seems it should, to my limmited understanding. 然后我想,对我有限的理解,也许全球环境中的mArgs不在MyFun2的范围内,尽管看起来应该如此。 So I added it at as an argument to each of the calling functions. 因此,我将其添加为每个调用函数的参数。 This did not change the result. 这并没有改变结果。

R3 <- function(A, B, mArgs){
   out <- mapply(function(x,y, ...){x*y1 + y*y2}, x=A, y=B,
                 MoreArgs = mArgs)
}
R3(1:3, 4:6, mArgs)
 Error in (function (x, y, ...)  : object 'y1' not found

Traceback: 追溯:

3. (function (x, y, ...) 
{
    x * y1 + y * y2
})(x = dots[[1L]][[1L]], y = dots[[2L]][[1L]], y1 = 1, y2 = 2) 
2. mapply(function(x, y, ...) {
    x * y1 + y * y2
}, x = A, y = B, MoreArgs = mArgs) 
1. R3(1:3, 4:6, mArgs) 

I tried replacing mArgs with the list itself in each of these functions, which in no case changed the result. 我在每个函数中都尝试用列表本身替换mArgs,在任何情况下都不会改变结果。

I am baffled. 我感到困惑。 Help! 救命!

To solve your problem, you can do: 要解决您的问题,您可以执行以下操作:

MyFun2 <- function(x, y, y1, y2){x*y1 + y*y2}

To answer why you method didn't work, see R-lang on dot-dot-dot : 要回答您的方法为什么不起作用的原因,请参阅dot-dot-dot上的R-lang:

2.1.9 Dot-dot-dot 2.1.9点-点-点

The '...' object type is stored as a type of pairlist. “ ...”对象类型存储为配对列表类型。 The components of '...' can be accessed in the usual pairlist manner from C code, but is not easily accessed as an object in interpreted code. 可以从C代码以通常的成对列表方式访问'...'的组件,但在解释代码中不容易将其作为对象进行访问。 The object can be captured as a list, so for example in table one sees 可以将该对象捕获为列表,因此例如在表一中可以看到

 args <- list(...) 

.... ....

 for (a in args) { 

If a function has '...' as a formal argument then any actual arguments that do not match a formal argument are matched with '...'. 如果函数以“ ...”作为形式参数,则所有与形式参数不匹配的实际参数都将以“ ...”匹配。

so in your have to extract y1 and y2 manually from the ... : 因此您必须从...手动提取y1y2

MyFun2 <- function(x, y, ...){
    additional.args <- list(...)
    y1 <- additional.args[[1]] 
    y2 <- additional.args[[2]]
    x*y1 + y*y2
}

MyFun2(1, 2, 1, 2)
# [1] 5

about moreArgs, it is for arguments that will not be vectorized over. 关于moreArgs,这是针对不会向量化的参数。 see following example: 请参阅以下示例:

mapply(function(x, y){
    print('----------------')
    print(x)
    print(y)
    x + y
}, x = 1:3, y = 1:3)

# [1] "----------------"
# [1] 1
# [1] 1
# [1] "----------------"
# [1] 2
# [1] 2
# [1] "----------------"
# [1] 3
# [1] 3
# [1] 2 4 6

mapply(function(x, y){
    print('----------------')
    print(x)
    print(y)
    x + y
}, x = 1:3, MoreArgs = list(y = 1:3))

# [1] "----------------"
# [1] 1
# [1] 1 2 3
# [1] "----------------"
# [1] 2
# [1] 1 2 3
# [1] "----------------"
# [1] 3
# [1] 1 2 3

#      [,1] [,2] [,3]
# [1,]    2    3    4
# [2,]    3    4    5
# [3,]    4    5    6

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM