通过do.call()将处理过的...参数传递给plot()

时间:2013-08-01 04:51:36

标签: r

我正在尝试编写一个方法来扩展一个S3对象的plot(),该对象本质上是一个xy.coords()列表的列表。我希望使用...的灵活性,但我需要处理其中的美学论点(即xaxtyaxt参数)。我写的测试函数如下:

#test of ... expansion and modification
test = function(x, ...) {
  # x is a list of xy.coords() lists

  vargs = list(...)
  str(vargs)
  #vargs = as.list(substitute(list(...)))[-1L]
  # plotting defaults for aesthetics if they are not explicitly set
  if (!'xaxt' %in% names(vargs)) vargs[['xaxt']] = 'n'
  if (!'yaxt' %in% names(vargs)) vargs[['yaxt']] = 'n'
  if (!'pch' %in% names(vargs)) vargs[['pch']] = 16
  if (!'cex' %in% names(vargs)) vargs[['cex']] = 0.5
  print(vargs)

  pargs = c(list(x=x[[1]]$x, y=x[[1]]$y), vargs)
  str(pargs)

  do.call(plot, pargs) # this produces a crazy plot with a bunch of text

  plot(x=x[[1]], ...) # this produces the desired results

  invisible(NULL)
}

我发出的电话是:

test(Y, xaxt='n', yaxt='n', pch=16, cex=0.5)

其中(为简洁而截断):

> Y[[1]]
$x
  [1]  0.001111111  0.501388889  1.001388889  1.501388889  2.001388889  2.501388889  3.001388889  3.501388889  4.001388889

$y
  [1] 0.132 0.123 0.126 0.143 0.145 0.123 0.128 0.131 0.140

正如我在test()的评论中指出的那样,将...扩展为参数列表,并通过plot将该列表传递给do.call创建了一个文字遍布各地 - 如此:

strange output from do.call(plot, pargs)

否则,将...直接传递给plot可以实现我的目标:

correct/expected plot output

我有什么问题吗,

  • 我处理...
  • 我如何将事情传递给do.call()

我是否完全错过了一个步骤/参数,或者这是R中的错误? 会议信息如下,并提前感谢您的帮助。

> sessionInfo()
R version 3.0.0 (2013-04-03)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] groan_1.0      roxygen2_2.2.2 digest_0.6.3  

loaded via a namespace (and not attached):
[1] brew_1.0-6    stringr_0.6.2 tools_3.0.0 

修改

这是我的问题的更多复制+粘贴兼容版本

#test of ... expansion and modification
test = function(x, method=c('do.call', 'dots'), ...) {
  # x is a list of xy.coords() lists

  vargs = list(...)
  str(vargs)
  #vargs = as.list(substitute(list(...)))[-1L]
  # plotting defaults for aesthetics if they are not explicitly set
  if (!'xaxt' %in% names(vargs)) vargs[['xaxt']] = 'n'
  if (!'yaxt' %in% names(vargs)) vargs[['yaxt']] = 'n'
  if (!'pch' %in% names(vargs)) vargs[['pch']] = 16
  if (!'cex' %in% names(vargs)) vargs[['cex']] = 0.5
  print(vargs)

  pargs = c(list(x=x[[1]]), vargs)
  str(pargs)

  method = match.arg(method)
  switch(method, 
         do.call={
           do.call(plot, pargs) # this produces a crazy plot with a bunch of text
         }, dots={
           plot(x=x[[1]], ...) # this produces the desired results
         })

  invisible(NULL)
}

Y = list(xy.coords(runif(100), runif(100)))

# this produces a crazy plot with a bunch of text
test(Y, method='do.call', xaxt='n', yaxt='n', pch=16, cex=0.5)

# this produces the desired results
test(Y, method='dots', xaxt='n', yaxt='n', pch=16, cex=0.5)

解决方案

@shadow的解决方案解决了我的问题。另一种方法是将ann=FALSE指定为传递给do.call()的列表中的参数。

1 个答案:

答案 0 :(得分:1)

问题是轴标签。你实质上是在做类似

的事情

积(X = C(0.001111111,0.501388889,1.001388889,1.501388889,2.001388889,2.501388889,3.001388889,3.501388889,4.001388889,0.501388889,1.001388889,1.501388889,2.001388889,2.501388889,3.001388889,3.501388889,4.001388889,0.501388889,1.001388889,1.501388889,2.001388889 ,2.501388889,3.001388889,3.501388889,4.001388889,0.501388889,1.001388889,1.501388889,2.001388889,2.501388889,3.001388889,3.501388889,4.001388889,0.501388889,1.001388889,1.501388889,2.001388889,2.501388889,3.001388889,3.501388889,4.001388889,0.501388889,1.001388889,1.501388889,2.001388889,2.501388889 ,3.001388889,3.501388889,4.001388889,0.501388889,1.001388889,1.5008888889,2.001388889,2.501388889,3.001388889,3.501388889,4.001388889))

要解决问题,请自行分配标签:

if (!'xlab' %in% names(vargs)) vargs[['xlab']] = names(x[[1]][2])
if (!'ylab' %in% names(vargs)) vargs[['ylab']] = names(x[[1]][1])