2014-08-29 35 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()