Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 为什么'missing'和默认参数在'lappy'调用的函数中不起作用?_R_Lapply - Fatal编程技术网

R 为什么'missing'和默认参数在'lappy'调用的函数中不起作用?

R 为什么'missing'和默认参数在'lappy'调用的函数中不起作用?,r,lapply,R,Lapply,我很惊讶missing在lappy调用的函数中似乎不起作用。假设我有以下功能: .add <- function(x, arg, ...) { if (missing(arg)) { arg <- 1 } print(match.call()) return(x + arg) } wrapper <- function(l, arg, ...) { return(lapply(l, .add, arg=arg, ...)) } 如果没有arg,我

我很惊讶
missing
lappy
调用的函数中似乎不起作用。假设我有以下功能:

.add <- function(x, arg, ...) {
  if (missing(arg)) {
    arg <- 1
  }
  print(match.call())
  return(x + arg)
}

wrapper <- function(l, arg, ...) {
  return(lapply(l, .add, arg=arg, ...))
}
如果没有
arg
,我希望得到相同的输出,但失败了:

wrapper(list(x=1:10, y=1:10))
#FUN(x = X[[1L]], arg = ..1)
# Error in FUN(X[[1L]], ...) : argument "arg" is missing, with no default
missing
在嵌套包装函数中工作,其中不使用
lappy
。 为什么它在
lappy
调用的函数中似乎没有效果

编辑:默认参数也不起作用:

.add <- function(x, arg=5, ...) {
  if (missing(arg)) {
    arg <- 1
  }
  print(match.call())
  return(x + arg)
}

wrapper(list(x=1:10, y=1:10))
#FUN(x = X[[1L]], arg = ..1)
# Error in FUN(X[[1L]], ...) : argument "arg" is missing, with no default

.add包装中没有
缺失
,因此它会在那里爆炸。在这种情况下,您不需要它,因为您使用的是可变参数。试试这个:

.add <- function(x, arg, ...) {
    if (missing(arg)) 
      arg <- 1
    print(match.call())
  return(x + arg)
}

wrapper <- function(l, ...) 
  return(lapply(l, .add, ...))
我被纠正了 下面的示例允许
missing
位于调用堆栈的底部,这可能是因为延迟计算。我不确定为什么你的例子不起作用。。。好奇

wrapper.c <- function(l, arg)
{
  if (missing(arg))
    arg <- 1
  print("I'm in c")
  arg
}

wrapper.b <- function(l, arg)
{
  print("I'm in b")
  wrapper.c(l, arg)
}

wrapper.a <- function(l, arg)
  wrapper.b(l, arg)

> wrapper.a(1)
[1] "I'm in b"
[1] "I'm in c"
[1] 1

wrapper.c首先,我要提到的是,我认为实现这一点的惯用方法是构造一个调用,然后对其求值。有关示例,请参见
write.csv
。我相信这段代码将使用该方法实现您想要的功能

wrapper <- function(X, arg, ...) {
  force(X) # optional; if X is missing, the error message will be more informative
  Call <- match.call(expand.dots=TRUE)
  Call[[1L]] <- as.name("lapply")
  Call$FUN <- as.name(".add")
  eval.parent(Call)
}
现在转到
lappy
中的缺失问题。这里我基本上有sgibb的代码,但添加了一条关于是否认为缺少arg的消息。我们似乎有一个奇怪的矛盾;消息告诉我们,
arg
没有丢失,但是当函数尝试访问它时,我们会收到一条错误消息,告诉我们,
arg
丢失

.add <- function(x, arg) {
  print(match.call())
  if(missing(arg)) {
    message("arg is missing in .add")
    x
  } else {
    message("arg is not missing")
    x + arg
  }
}
wrapper <- function(l, arg) {lapply(l, .add, arg=arg)}
wrapper(1)
## FUN(x = 1[[1L]], arg = ..1)
## arg is not missing
## Error in FUN(1[[1L]], ...) : argument "arg" is missing, with no default
但是当我们用一个变量名替换点时,它会像预期的那样工作

apply4 <- function(X, FUN, hm) { 
  print(match.call())
  FUN(X, hm)
}
wrapper4 <- function(l, arg) {apply4(l, .add, hm=arg)}
wrapper4(1)
## apply4(X = l, FUN = .add, hm = arg)
## FUN(x = X, arg = hm)
## arg is missing in .add
## [1] 1

我认为问题出在
wrapper
而不是
lappy
。将形式参数
arg
wrapper
中完全删除(或给它一个默认值),它对我有效。从文档
?missing
:当前
missing
只能在定义参数的函数的直接体中使用,不能在嵌套函数体或本地调用中使用。这在将来可能会改变。这有帮助吗?@joran:没错,但是
.add
是一个内部函数,文档化的函数是
wrapper
(而
arg
的可能默认参数取决于输入
.add
)的子集。)@Arun:你是对的,但这是有效的:
wrapper2我很想知道为什么会发生这种情况。。。我已经试了好一阵子去理解,但还没有理解。如果我找到什么,我会回信的。或者是时候提供我的第一笔赏金了!:)你是对的,但它并没有真正回答我的问题。顺便说一句,
arg
的默认值取决于进入
的子集。添加
(例如
mean(x)
)。您是否也看到了我给出的两个解决方案中的第一个?也许我不明白你的问题。如果您有
arg
作为
wrapper
的参数,但在wrapper中没有
丢失
,那么您的程序在调用
之前就爆炸了。添加
对我来说似乎是合乎逻辑的。如果wrapper的参数都是可变的,那么在调用
之前去掉
wrapper
我的函数中的arg。添加
,否则将看不到
打印(match.call())
的输出。IMHO
arg
return(x+arg)
(惰性求值)中使用时首先求值。你说得对,我被纠正了。。。虽然我仍然不确定你为什么要这么做。没有任何答案,但也探索了类似的行为。非常感谢这项伟大的调查。我将通过构建我自己的调用来使用您的第一个解决方法。现在只剩下一个问题:为什么手动扩展(
.1
)有效而自动扩展失败?是的,我也有这个问题,尽管我的好奇心目前已经满足了。我的猜测是,要真正理解点扩展是如何工作的,必须深入研究C代码。感谢所有的研究和有趣的问题,@sgibb。似乎有默认值的(正式)参数仍然被视为缺少
)(只是在调试函数时注意到了这一点,偶然发现了这个问题)。e、 g.,
f1@Aaron:自从R3.2.0以来,一切都按预期进行。这是R:中的一个错误。
f1 <- function(x=1) {print(match.call()); x}
f2 <- function(x) {f1(x=x)}
f1()
## f1()
## [1] 1
f2()
## f1(x = x)
## Error in f1(x = x) : argument "x" is missing, with no default
.add <- function(x, arg) {
  print(match.call())
  if(missing(arg)) {
    message("arg is missing in .add")
    x
  } else {
    message("arg is not missing")
    x + arg
  }
}
wrapper <- function(l, arg) {lapply(l, .add, arg=arg)}
wrapper(1)
## FUN(x = 1[[1L]], arg = ..1)
## arg is not missing
## Error in FUN(1[[1L]], ...) : argument "arg" is missing, with no default
apply3 <- function(X, FUN, ...) { 
  print(match.call())
  FUN(X, ...)
}
wrapper3 <- function(l, arg) {apply3(l, .add, arg=arg)}
wrapper3(1)
## apply3(X = l, FUN = .add, arg = arg)
## FUN(x = X, arg = ..1)
## arg is not missing
## Error in FUN(X, ...) : argument "arg" is missing, with no default
apply4 <- function(X, FUN, hm) { 
  print(match.call())
  FUN(X, hm)
}
wrapper4 <- function(l, arg) {apply4(l, .add, hm=arg)}
wrapper4(1)
## apply4(X = l, FUN = .add, hm = arg)
## FUN(x = X, arg = hm)
## arg is missing in .add
## [1] 1
apply3b <- function(X, FUN, ...) { 
  print(match.call())
  FUN(X, ..1)
}
wrapper3b <- function(l, arg) {apply3b(l, .add, arg=arg)}
wrapper3b(1)
## apply3b(X = l, FUN = .add, arg = arg)
## FUN(x = X, arg = ..1)
## arg is missing in .add
## [1] 1