0

我正在尝试为本质上是列表列表的 S3 对象编写扩展 plot() 的方法xy.coords()。我想要使​​用的灵活性,...但我需要处理其中的论点以实现美学(即xaxt论点yaxt)。我写的一个测试函数如下:

#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(),扩展...为参数列表并将该列表传递给plotviado.call会创建一个带有散布在各处的文本的图 - 如下所示:

do.call(plot, pargs) 的奇怪输出

否则,...直接传递给plot我想要的东西:

正确/预期的绘图输出

是不是我做错了什么

  • 我的处理...
  • 我怎么把东西传递给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()

4

1 回答 1

1

问题是轴标签。你本质上是在做类似的事情

plot(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.501388889, 2.001388889, 2.501388889, 3.001388889, 3.501388889, 4.001388)

要解决此问题,只需自己分配标签:

if (!'xlab' %in% names(vargs)) vargs[['xlab']] = names(x[[1]][2])
if (!'ylab' %in% names(vargs)) vargs[['ylab']] = names(x[[1]][1])
于 2013-08-01T06:30:27.427 回答