2014-08-29 90 views
2

我是使用R的力量创建图形输出的新手。将文本与可变大小的文本对齐R

我使用metafor-package中的forest()函数来创建我的元分析的Forest图。我使用循环生成多个图,然后通过png()保存它们。

for (i in 1:ncol(df)-2)){ 
    dat <- escalc(measure="COR", ri=ri, ni=ni, data=df) # Calcultes Effect Size 
    res_re <- rma.uni(yi, vi, data=dat, method="DL", slab=paste(author)) # Output of meta-analysis 

    png(filename=path, width=8.27, height=11.69, units ="in", res = 210) 
    forest(res_re, showweight = T, addfit= T, cex = .9) 
    text(-1.6, 18, "Author(s) (Year)", pos=4)  
    text(1.6, 18, "Correlation [95% CI]", pos=2) 
    dev.off() 
} 

如果图的大小相等,这很好用。但是,循环的每次迭代都在林地中集成了不同数量的研究。因此,文本元素不在正确的位置,许多研究的森林情节看起来有点奇怪。我有两个问题:

  1. 我该如何调整的“作者(S)(年)”和“相关性[95%CI]”自动森林积的大小变化的这样的标题是以上森林表的上线?
  2. 我该如何缩放森林情节的大小,使所有情节的文本元素的宽度和大小相同,并且对于每个附加研究,只需添加一条新行(改变高度)?

每个林积应该是这样的:

enter image description here

+0

你想做到这一点在metfor只包或其他解决方案也将可以接受吗? – rnso 2014-08-29 12:23:42

+0

metafor会很好,但如果你有另一种解决方案。请让我知道 – jeffrey 2014-08-29 14:40:54

+0

如果您在这里发布dput(df)的输出,那么测试代码会更容易。 – rnso 2014-08-30 01:47:42

回答

1

这里是你必须做的就是这个工作是什么:

  1. 我会跨越修复xlim因此有一个固定的位置可以放置“作者(年)”和“相关性[95%CI]”标题。在生成了一个森林图后,请看par()$usr[1:2]。使用这些值作为起点来调整xlim,以便它适用于所有图。然后将这两个值用于text()

  2. 每个图中有k行。标题应该在两行以上。因此,使用text(<first xlim value>, res_re$k+2, "Author(s) (Year)", pos=4)text(<second xlim value>, res_re$k+2, "Correlation [95% CI]", pos=2)

  3. cextext()给你调用指定forest()相同的值。

  4. 最后一部分是棘手的。您已修复cex,因此文本元素的大小在整个绘图中应该是相同的。但是,如果有更多的研究,那么k行就会挤入更少的空间,所以它们变得更加分离。如果我正确地理解了你,你想通过调整图的实际高度来保持各行之间的间距相等。实质上,这将需要height中的的函数调用png()。对于每一项额外的研究,需要将额外的金额添加到height以便行间距保持不变,所以沿着height=<some factor> + res_re$k * <some factor>的行。但作为k的函数的高度增加也可以是非线性的。做对这需要很多尝试和错误。可能有一个聪明的方式来确定这个编程(挖掘到?par和也许?strheight)。

所以更容易为他人帮腔,你的问题的最后一部分可以归结为:如何做我必须调整打印设备的height值,使行之间的绝对间距在plot(1:10)plot(1:20)保持不变?这本身就是一个有趣的问题,所以我将把它作为一个单独的问题发布。

+0

问题在这里:http://stackoverflow.com/q/25742400/2615367 – Wolfgang 2014-09-09 10:32:43

1

ad 4 .:在Wolfgangs问题(Constant Absolute Spacing of Row in R Plots)中,您将找到如何根据其中的行数来绘制绘图高度。

对于forest()它会有点不同,因为此功能在内部修改par("mar")值。

但是,如果将边距设置为零,则只需在forest()-函数中包含属性yaxs="i",以便y轴将针对数据范围进行分段,而不是其他任何内容。该设备需要配置为具有以英寸/行(见下文)和res为像素/英寸(分辨率)的高度(length(ma$yi)+4.5)*fact*resfact

4.5取决于如果你已经在你的荟萃分析模型左addfit=Tintercept=T(在这种情况下forest()内部设置ylim <- c(-1.5, k + 3))。否则,你将不得不使用2.5(比它将是ylim <- c(0.5, k + 3))。

如果你喜欢使用的利润率,你会做以下的(我编辑的以下部分,在我认识的一些错误):

res <- 'your desired resolution' # pixels per inch 
fact <- par("mai")[1]/par("mar")[1] # calculate inches per line 
### this following part is copied from inside the forest()-function. 
# forest() modifies the margin internally in the same way. 
par.mar <- par("mar") 
par.mar.adj <- par.mar - c(0, 3, 1, 1) 
par.mar.adj[par.mar.adj < 0] <- 0 
### 
ylim <- c(-1.5, length(ma$yi)+3) # see above 
ylim.abs <- abs(ylim[1])+abs(ylim[2])-length(ma$yi) # calculate absolute distance of ylim-argument 
pixel.bottom <- (par.mar.adj[1])*fact*res # calculate pixels to add to bottom and top based on the margin that is internally used by forest(). 
pixel.top <- (par.mar.adj[3])*fact*res 
png(filename='path', 
    width='something meaningful', 
    height=((length(ma$yi)+ylim.abs)*fact*res) + pixel.bottom + pixel.top, 
    res=res) 
par(mar=par.mar) # make sure that inside the new device the margins you want to define are actually used. 
forest(res_re, showweight = T, addfit= T, cex = .9, yaxs="i") 
... 
dev.off()