- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想编写一个调用 plot()
的函数和legend()
如果用户可以指定一些附加参数,然后将它们传递给 plot()
,那将是理想的选择。或legend()
。我知道我可以使用 ...
为两个函数之一实现此目的:
foo.plot <- function(x,y,...) {
plot(x,y,...)
legend("bottomleft", "bar", pch=1)
}
foo.plot(1,1, xaxt = "n")
这通过了xaxt = "n"
来策划。但是有没有一种方法可以通过例如title = "legend"
到legend()
调用时无需在函数头中预先指定参数?
更新已接受的答案:我认为 VitoshKa 的方式是实现我想要的最优雅的方式。然而,有一些小问题我必须解决,直到它按我想要的方式工作。
首先,我检查了要传递给 legend
的参数。以及 plot
。为此,第一步是查看 legend
的哪些参数是 legend
所独有的并且不是情节和/或标准的一部分:
legend.args <- names(formals(legend))
plot.args <- c(names(formals(plot.default)), names(par()))
dput(legend.args[!(legend.args %in% plot.args)])
我使用dput()
在这里,因为行 plot.args <- c(names(formals(plot.default)), names(par()))
总是调用一个我不想要的新的空地 block 。所以,我使用了 dput
的输出在以下函数中。
接下来,我必须处理重叠的参数(通过 dput(largs.all[(largs.all %in% pargs.all)])
获取它们)。对于某些函数来说这是微不足道的(例如 x
、 y
),其他函数则传递给这两个函数(例如 pch
)。但是,在我的实际应用程序中,我什至使用其他策略(例如 adj
的不同变量名称,但在本示例中未实现)。
最后,do.call
必须以两种方式改变功能。首先,what 部分(即称为函数)需要是一个字符(即 'plot'
而不是 plot
)。并且参数列表的构造必须略有不同。
foo.plot <- function(x,y,...) {
leg.args.unique <- c("legend", "fill", "border", "angle", "density", "box.lwd", "box.lty", "box.col", "pt.bg", "pt.cex", "pt.lwd", "xjust", "yjust", "x.intersp", "y.intersp", "text.width", "text.col", "merge", "trace", "plot", "ncol", "horiz", "title", "inset", "title.col", "title.adj")
leg.args.all <- c(leg.args.unique, "col", "lty", "lwd", "pch", "bty", "bg", "cex", "adj", "xpd")
dots <- list(...)
do.call('plot', c(list(x = x, y = x), dots[!(names(dots) %in% leg.args.unique)]))
do.call('legend', c(list("bottomleft", "bar"), dots[names(dots) %in% leg.args.all]))
}
foo.plot(1,1,pch = 4, title = "legendary", ylim = c(0, 5))
在此示例中,pch
被传递给 plot
和legend
, title
仅传递给legend
,和ylim
仅限plot
。
根据 Gavin Simpson 的评论更新 2(另请参阅 Vitoshka 的回答中的评论):
(i) 是的。
(ii) 它总是可以是一个字符。但如果你有一个与函数同名的变量,那么你需要在 do.call
中引用函数名。 :
min.plot <- function(x,y,plot=TRUE) if(plot == TRUE) do.call(plot, list(x = x, y = y))
min.plot(1,1)
Error in do.call(plot, list(x = x, y = y)) :
'what' must be a character string or a function
(iii) 您可以使用c(x = 1, y = 1, list())
而且效果很好。但是,我真正所做的(不是在我给出的示例中,而是在我的实际函数中)如下:c(x = 1, y = 1, xlim = c(0, 2), list(bla='foo'))
请将其与: c(list(x = 1, y = 1, xlim = c(0, 2)), list(bla='foo'))
进行比较
在第一种情况下,列表包含两个元素 xlim
, xlim1
和xlim2
(每个都是标量),在后一种情况下,列表只有 xlim
(这是长度为2的向量,这就是我想要的)。
所以,对于我的例子来说,你的所有观点都是正确的。但是,对于我的实际函数(具有更多变量),我遇到了这些问题并想在这里记录它们。抱歉,不准确。
最佳答案
自动方式:
foo.plot <- function(x,y,...) {
lnames <- names(formals(legend))
pnames <- c(names(formals(plot.default)), names(par()))
dots <- list(...)
do.call('plot', c(list(x = x, y = x), dots[names(dots) %in% pnames]))
do.call('legend', c("bottomleft", "bar", pch = 1, dots[names(dots) %in% lnames]))
}
pch 必须从 lname 中过滤掉,以避免在用户提供“pch”的情况下在 legend
调用中出现重复,但您已经明白了。Carl W 于 2012 年 1 月编辑:“do.call”仅适用于引号中的函数,如 Henrik 的更新中所示。我在这里对其进行了编辑,以避免将来出现困惑。
关于function - 有没有办法在 R 的函数中使用两个 '...' 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4124900/
我是一名优秀的程序员,十分优秀!