【问题标题】:Modifying dots (...) inside a function修改函数内的点 (...)
【发布时间】:2015-12-08 15:19:29
【问题描述】:

我正在尝试修改自定义函数中的点 (...)。这是我的plot2 函数的简化示例,它使用type="p"(默认)在屏幕上显示一个绘图,并使用type="l" 保存一个svg。当 ... 绘图选项之一已经在函数中时,问题就会出现。在此示例中,"type" 与多个实际参数匹配。

plot2 <-function(...){
plot(...) #visible on screen

svg("c:/temp/out.svg") #saved to file
plot(...,type="l")
dev.off()
}

#This works
plot2(1:10)
#This does not work because type is redefined
plot2(1:10, type="o")

我尝试将点放在函数内部的list 中并对其进行修改,但plot 不接受列表作为输入。

#Does not work
plot2 <-function(...){
plot(...)

dots <<-list(...)
print(dots)
if("type" %in% names(dots)) dots$type="l"
print(dots)

svg("c:/temp/out.svg")
plot(dots)
dev.off()
}
plot2(1:10, type="o")
Error in xy.coords(x, y, xlabel, ylabel, log) : 
  'x' is a list, but does not have components 'x' and 'y'

【问题讨论】:

    标签: r


    【解决方案1】:

    如果您想转发... 的修改版本,您需要做两件事:

    1. 捕捉
    2. 通过do.call转发捕获的点。

    它的工作原理如下:

    plot2 = function (...) {
        # capture:
        dots = list(...)
    
        # modify:
        dots$type = 'l'
    
        # forward call:
        do.call(plot, dots)
    }
    

    一般来说,do.call(f, list(‹…›)) 等价于f(‹…›)

    【讨论】:

    • 谢谢。简单有效。
    【解决方案2】:

    对于你想要的,有一个更简单(更好)的方法,你不需要接触...。通过明确定义需要特殊处理的参数,您可以将它们排除在所有... 之外。这也是一种理智的方法,它更明确地说明了函数的作用(在其形式参数中)。操作方法如下:

    plot2 <- function(x, type = "p", ...) {
      plot(x, type = type, ...) #visible on screen
    
      svg("out.svg") #saved to file
      plot(x, ..., type = "l")
      dev.off()
    }
    
    plot2(1:10)
    plot2(1:10, type = "o")
    

    【讨论】:

    • 我提供的示例是简化的,您的解决方案对于我的实际功能来说不是最佳的。在我的真实示例中,plot 函数是一个自定义绘图函数,具有接近 50 个参数。 plot2 函数只是一个包装器,用于显示绘图并以多种格式保存。
    • 抱歉,它仍然有效。并不是所有的参数都可以传递给...,而只有您在函数中以特殊方式操作的少数参数必须显式地从...中取出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 2021-09-24
    • 2015-01-31
    • 2014-03-30
    • 2013-10-24
    • 1970-01-01
    • 2019-10-25
    相关资源
    最近更新 更多