0

我有一个看起来像这样的宽表格:

ID  Test_11 LVL11  Score_X_11 Score_Y_11  Test_12 LV12  Score_X_12  Score_Y_12
1   A       I      100        NA          NA      NA    100         100
2   A       II     90         100         B       II    90          85 
3   NA      NA     NA         NA          B       II    90          NA
4   A       III    100        80          A       III   75          75
5   B       I      NA         90          NA      NA    60          50
6   B       I      70         100         NA      NA    NA          NA
7   B       II     85         NA          A       I     60          60

还有一个用于排序的表格,看起来像这样

Test_11   A
Test_11   B
Test_12   A
Test_12   B

第二张表告诉我们的是,对于 Test_11,有两个版本,A 和 B(对于 Test_12 相同)。

我正在尝试创建一系列箱线图来绘制 Test_11 和 Test_12 的每个组合及其各自版本(A、B)的分布。因此,对于 Test_11==A,创建的箱线图将具有三组(I、II、III),然后是来自 Test_11==A 的子集的结果图形信息,然后对于 Test_11==B、Test_12==A 也是如此, 和 Test_12==B。在此示例中,总共应该创建 4 个图表。

我在 R 中拥有的是:

z <- subset(df, df$Test_11=="A")
plot(z$LVL11, z$Score_X_11, varwidth = TRUE, notch = TRUE, xlab = 'LVL', 
     ylab = 'score')

我想要并且无法弄清楚如何做的是编写一个 for 循环来为我做子集,以便我可以为我的实际数据集自动执行此操作,其中包含几十个这些组合。

感谢您的任何帮助和指导。

4

2 回答 2

1

“直截了当的方式”

也许您应该在循环之前将所有逻辑向量保存在 data.frame 或矩阵中:

selections <- matrix(nrow = nrow(df), ncol = 4)
selections[,1] <- df$Test_11 == "A"
selections[,2] <- df$Test_11 == "B"
selections[,3] <- df$Test_12 == "A"
selections[,4] <- df$Test_12 == "B"
# etc...
par(mfcol = c(2, 2)) # here you should customize at will...
for (i in 1:4) {
  z <- subset(df, selections[,i])
  plot(z$LVL11, z$Score_X_11, varwidth = TRUE, 
       notch = TRUE, xlab = 'LVL', 
       ylab = 'score')
}

您可以更改您的代码,而不是使用z$Score_X_11,使用z[,string]。的值string应该用paste(或其他字符串操作函数)构造。例如:

v <- c("X", "Y")
n <- c("11", "12")
for (i in 1:2) {
  for (j in 1:2) {
    string <- paste("Score", v[i], n[i], sep = "_")
    print(string)
  }
}

类似的推理将用于这些z$LVLXX值,因此您应该能够找到一种方法来适应它。

另一种方式,使用 ggplot2 和 reshape2

我对使用格子图形(就像在其他 anwser 中一样)不是很有经验,但我知道一点 ggplot2,所以我决定接受挑战并尝试一下。这不是很好,但至少有效:

# df <- read.table("data.txt", header = TRUE, na.string = "NA")
require(reshape2)
require(ggplot2)

# Melt your data.frame, using the scores as the "values":
mdf <- melt(df[,-1], id = c("LVL11", "LV12", "Test_11", "Test_12"))

# loop through level types:
for (lvl in c("LVL11", "LV12")) {
  # looping through values of test11
  for (test11 in c("A", "B")) {
    # Note the use of subset before ggplot
    p <- ggplot(subset(mdf, Test_11 == test11), aes_string(x=lvl, y="value"))
    # I added the geom_jitter as in the example given there were only a few points
    g <- p + geom_boxplot(aes(fill = variable)) + geom_jitter(aes(shape = variable))
    print(g) # it is necessary to print p explicitly like this in order to use ggplot in a loop
    # Finally, save each plot with a relevant name:
    savePlot(paste0(lvl, "-t11", test11, ".png")) 
    # (note that savePlot has some problems with RStudio iirc)

  }
  # Same as before, but with test_12
  for (test12 in c("A", "B")) {
    p <- ggplot(subset(mdf, Test_12 == test12), aes_string(x=lvl, y="value"))
    g <- p + geom_boxplot(aes(fill = variable)) + geom_jitter(aes(shape = variable))
    print(g) 
    savePlot(paste0(lvl, "-t12", test12, ".png"))
  }
}

如果有人知道如何使用格子图形,或者facet_grid在这种情况下,我可以将所有图形放在一张图像中,我很想听听如何。

干杯。

于 2013-10-25T14:38:41.747 回答
1

经典plyr解决方案(HT 到@hadleywickham)

require(plyr); require(lattice); require(gridExtra)
bplots <- dlply(dat, .(Test_11, Test_12), function(df){
  bwplot(Score_X_11 ~ LVL11, data = df)
})
do.call('grid.arrange', bplots)

在此处输入图像描述

于 2013-10-25T16:04:56.950 回答