2014-04-05 61 views
2

我有一個數據幀,其中包含一列分類數據(兩個可能的值)和多個變量列。我需要繪製多個箱形圖,每個變量列一個。每個圖比較列1中給出的兩個分類組之間的變量值。到目前爲止,我通過爲每列編寫單獨的圖表調用來工作。使用R中的數據幀列繪製多個箱圖使用R

#CREATE DATASET 
mydata <- data.frame(matrix(rlnorm(30*10,meanlog=0,sdlog=1), nrow=30)) 
colnames(mydata) <- c("categ", "var1","var2", "var3","var4", "var5", "var6", "var7", "var8", "var9") 
mydata$var2 <- mydata$var2*5 
mydata$categ <- sample(1:2) 
mydata 

#LAYOUT 
par(mfrow=c(3,3), mar=c(4,4,0.5,0.5), mgp = c(1.5, 0.3, 0), tck = -0.01) 

#BOXPLOTS 
boxplot(var1 ~ categ, data = mydata, outpch = NA, ylim = c(0, 8), Main = "Title", ylab="VarLevel", tck = 1.0, names=c("categ1","categ2")) 
stripchart(var1 ~ categ, data = mydata, vertical = TRUE, method = "jitter", ylim = c(0, 8), pch = 21, cex = 1, col=c(rgb(255, 0, 0, 100, max = 255), rgb(0, 0, 255, 100, max = 255)), bg = rgb(255, 255, 255, 10, max = 255), add = TRUE) 
test <- wilcox.test(var1 ~ categ, data = mydata) 
pvalue <- test$p.value 
pvalueformatted <- format(pvalue, digits=3, nsmall=2) 
mtext(paste(colnames(mydata)[2], " p = ", pvalueformatted), side=1, line=-13, at=0.9, cex = 0.6) 

boxplot(var2 ~ categ, data = mydata, outpch = NA, ylim = c(0, 40), Main = "Title2", ylab="VarLevel", tck = 1.0, names=c("categ1","categ2")) 
stripchart(var2 ~ categ, data = mydata, vertical = TRUE, method = "jitter", ylim = c(0, 40), pch = 25, cex = 1, col=c(rgb(255, 0, 0, 100, max = 255), rgb(0, 0, 255, 100, max = 255)), bg = rgb(255, 255, 255, 10, max = 255), add = TRUE) 
test <- wilcox.test(var2 ~ categ, data = mydata) 
pvalue <- test$p.value 
pvalueformatted <- format(pvalue, digits=3, nsmall=2) 
mtext(paste(colnames(mydata)[3], " p = ", pvalueformatted), side=1, line=-13, at=0.9, cex = 0.6) 

兩個問題:
1)我想用一個函數或for循環腳本情節呼籲每個數據列。不知道如何做到這一點。我看到一些相關的帖子,但無法完成。現在嘗試使用基本函數,但如果需要,可以考慮使用ggplot或其他函數。
2)作爲循環/函數的一部分,有沒有辦法調整每個圖的y軸比例以適應變量的範圍?因此,對於一個給定的列,如果最大值是2,y軸的規模將上升至4。如果max爲100,y軸將上升到110

思想認識

+0

一個很好的,可重複的問題 - 謝謝。 – jbaums

回答

2

我會sapply在列號和子集mydata的向量上添加到函數內的感興趣列。通過遍歷列號而不是列本身,您可以輕鬆訪問正確的colname以便稍後添加到圖中。

您還需要在第3面(頂部)添加一個較小的外部邊距(oma),以便可以在前3個圖中打印p值。

要解決第二個問題 - 即減少y限制以適應數據範圍 - 如果指定outline=FALSE來抑制繪製異常值,將會自動執行此操作。 (在您的代碼中,您只需提供NA作爲繪圖角色來隱藏它們,但boxplots仍然在確定軸限制時將它們視爲數據的一部分。)但是,通過設置outline=FALSE,計算出的y限制將不適合任何我們現在修改爲points,因爲它更簡單一些,否則這些異常值會被stripchart調用繪製出來。

par(mfrow=c(3,3), mar=c(3, 3, 0.5, 0.5), mgp = c(1.5, 0.3, 0), tck = -0.01, 
    oma=c(0, 0, 1, 0)) 

sapply(seq_along(mydata)[-1], function(i) { 
    y <- mydata[, i] 
    boxplot(y ~ mydata$categ, outline=FALSE, ylab="VarLevel", tck = 1.0, 
      names=c("categ1","categ2"), las=1) 
    points(y ~ jitter(mydata$categ, 0.5), 
    col=ifelse(mydata$categ==1, 'firebrick', 'slateblue')) 
    test <- wilcox.test(y ~ mydata$categ) 
    pvalue <- test$p.value 
    pvalueformatted <- format(pvalue, digits=3, nsmall=2) 
    mtext(paste(colnames(mydata)[i], " p = ", pvalueformatted), side=3, 
     line=0.5, at=0.9, cex = 0.6) 
}) 

注意我還修改了mtext調用上側3繪製,而不是指定方1大的負利潤率。

boxplots

+0

Arg。你在我之前2秒就到了那裏。 :) –

+1

過去幾天我們一直在進行着史詩般的戰鬥;) – jbaums

+0

了不起的解決方案和我正在尋找的東西。謝謝。試圖確保我明白:seq_along在做什麼?另外,通過這個解決方案,如果列數很多,我怎麼能限制每頁顯示12個圖?我是否必須將我的數據框分解爲單獨的12列數據框? – marcel