通过嵌套函数传递相同名称的参数

5
我正在创建一个简单的图表,它使用一个绘图函数调用另一个绘图函数来添加平滑线。第二个函数是lines(),它需要一些标准的基本图形参数。第一个函数也使用了同名参数。现在我想改变第二个图的一些元素,而不改变第一个图。我至少可以想到以下几种选择:
  • 分别绘制每个图
  • 重写函数以包含唯一命名的参数,以传递给第二个绘图函数
  • 为此创建一个新的绘图函数,可能使用ggplot2

我开始思考,是否有可能在不重写任何内容的情况下,将参数值传递给嵌套函数。请注意,在这个问题中,我不是要求编写一个绘图函数 - 我可以根据需要自己编写,我是在问是否可以在traceplot的参数列表中指定一个参数,只有当它也是traceplot的命名参数时才会传递给lines。例如:

require(coda)
require(geoRglm)

# Some example data
mcmc <- c(0, 0, 0, 0, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 
0.5, 1, 0.5, 0, 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
0, 0.5, 0.5, 0, 0.5, 1, 0, 0.5, 1, 0.5, 0.5, 0.5, 0, 0.5, 0.5, 
0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0, 0.5, 0, 0, 0, 
0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0, 0.5, 1, 1, 0, 1, 0, 
0, 0.5, 0, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0, 1, 0.5, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 
1.5, 1, 1.5, 1, 1, 1, 1, 0.5, 0.5, 1, 1, 1.5, 1.5, 1.5, 1, 1.5, 
1.5, 1.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.5, 1, 1.5, 1.5, 
1, 1.5, 1.5, 1, 1, 1, 1, 1)

# Input parameters for mcmc object
input <- structure(list(S.scale = 3.75e-05, Htrunc = "default", S.start = "default", 
    burn.in = 0, thin = 100, n.iter = 20000, phi.start = 0, phi.scale = 1), .Names = c("S.scale", 
"Htrunc", "S.start", "burn.in", "thin", "n.iter", "phi.start", 
"phi.scale"), class = "mcmc.geoRglm")


# create mcmc object
mcmc_obj <- create.mcmc.coda( mcmc , mcmc.input = input )


#Plot - smooth = TRUE draws the smooth line through the data
traceplot( mcmc_obj , smooth = TRUE , main = "Default")


# Changing the colour argument passes the same argument through to the lines function called to plot the smooth line
traceplot( mcmc_obj , smooth = TRUE , col = 2 , main = "Change colour to red")

enter image description here

# In the source code of traceplot 'lines()' is called to plot the smooth line.
# Can I specify a colour argument to be passed only to lines without altering
# the function?
# Excerpt from the source code of traceplot:

function (x, smooth = FALSE, col = 1:6, type = "l", ylab = "", 
    ...) 
{
... some code here then...
if (smooth) {
            for (k in 1:nchain(x)) lines(lowess(xp, yp[, k]) 
        }
} 

我明白你的意思,但我认为没有办法在不改变“traceplot”函数的情况下完成这个任务。 - Ben Bolker
@BenBolker,我认为这可能是情况,但我想要确认一下,因为如果有的话会很有用。我可能只需要在ggplot2中设计出一些简单的东西。每个人都喜欢那些灰色背景。 - Simon O'Hanlon
我从不这样做,我总是在加载包后立即使用theme_set(theme_bw())。 (您应该查看coda包中的xyplot.mcmcscapeMCMC包... scapeMCMC :: plotTrace函数可能会根据其col.loess vs. col.trace参数执行您想要的操作... - Ben Bolker
1
你的摘录有点误导性,for循环中的函数调用会在下一行继续,整个调用是 lines(lowess(xp, yp[, k]), col = scol[k]),其中scol <- rep(col, length = nchain(x)),因此很明显如果不改变函数(例如添加参数scol并删除上面的定义),就无法更改颜色。 - Jouni Helske
@Hemmo 我错过了括号的结束线。我以为col指的是列的位置或其他什么东西。不过,正如我所指出的那样,这个函数的语义并不是这个问题的重点。重写这个函数就像向traceplot添加一个参数,比如说lcol。这个问题的重点是要知道我提出的想法是否可行。 - Simon O'Hanlon
有没有办法将一个“par”配置传递给一个函数,将另一个“par”配置传递给另一个函数?我们可以像这样绘制图形plot(x,y,"col"="red"),也就是说,用字符串命名参数。 - Julián Urbano
1个回答

1

您可以使用两个列表传递不同的参数:

myfun <- function(x,y,par1=NULL,par2=NULL){
  if(is.null(par1)){
    plot(x,y)
  }else{
    do.call(plot,c(list(x=x,y=y),par1))
  }
  if(is.null(par2)){
    lines(x,y)
  }else{
    do.call(lines,c(list(x=x,y=y),par2))
  }
}

par1 用于 plot 函数的参数,par2 用于 lines 函数的参数。如果有这些参数,则使用 do.call 函数。

myfun(1:10,1:10) # no params
myfun(1:10,1:10,par1=list(pch=20)) # params only to plot
myfun(1:10,1:10,par1=list(pch=20),par2=list(col="red",lwd=2)) # params to plot and lines

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接