在箱线图中并排放置相应的箱子

Placing corresponding boxes side by side in boxplots

我在轮流发言时有词的持续时间。我想比较前最后位置的单词持续时间与最终位置相同单词的持续时间。这是一些可重现的数据:

df <- data.frame(
  word1 = c(sample(LETTERS[1:5], 10, replace = T)),
  word2 = c(sample(LETTERS[1:5], 10, replace = T)),
  word3 = c(sample(LETTERS[1:5], 10, replace = T)),
  word4 = c(sample(LETTERS[1:5], 10, replace = T)),
  word5 = c(sample(LETTERS[1:5], 10, replace = T)),
  dur1 = c(round(abs(rnorm(10)),2)),
  dur2 = c(round(abs(rnorm(10)),2)),
  dur3 = c(round(abs(rnorm(10)),2)),
  dur4 = c(round(abs(rnorm(10)),2)),
  dur5 = c(round(abs(rnorm(10)),2))
)
df
# convert words to character:
df[,1:5] <- lapply(df[,1:5], as.character)

该数据中的预决赛排名包括 df[,1:4],而最终排名仅包括 df$word5。现在我还有一组目标词,我希望在箱线图中绘制其在任一条件下的持续时间:

targets <- c("A", "C", "E")

我很难回答的问题是如何在箱形图中并排绘制目标在任一条件下的持续时间。到目前为止我试过的是: 我已经将 targets 中包含的前最终位置的单词组合在一个向量中:

word1to4 <- c(df$word1[df$word1 %in% targets], df$word2[df$word2 %in% targets], df$word3[df$word3 %in% targets],
          df$word4[df$word4 %in% targets])

并将它们的持续时间合并到另一个向量中:

dur1to4 <- c(df$dur1[df$word1 %in% targets], df$dur2[df$word2 %in% targets], df$dur3[df$word3 %in% targets],
         df$dur4[df$word4 %in% targets])

并对最终位置的单词和单词的持续时间做同样的事情:

word5 <- df$word5[df$word5 %in% targets]
dur5 <- df$dur5[df$word5 %in% targets]

现在我可以绘制词前和词尾的持续时间,但不幸的是只能在两个不同的箱线图中绘制:

par(mfrow=c(1,2))
boxplot(dur1to4 ~ word1to4, main="Words 1-4", col="red", frame=F)
boxplot(dur5 ~ word5, main="Word 5", col="blue", frame=F)

我宁愿在单个箱线图中并排显示目标词的持续时间。如何实现?

解决这个问题的一种方法是创建另一个向量来指示单词属于哪个分组,然后使用箱线图中的公式表达式对结果进行正确分组。下面,我创建了一个数据框来保存所有数据和绘图。

#Create data frames to hold the data
out<-data.frame(group="word1to4", word=word1to4, duration=dur1to4)
out5<-data.frame(group="word 5", word=word5, duration=dur5)
#Data frame with all of the data
answer<-rbind(out, out5)

#plotting grouping by Word groups and word, add a legend
par(mfrow=c(1,1))
boxplot(answer$duration ~ answer$group +answer$word, main="Words", col=c("red", "blue"), frame=F, las=2)
legend("top",legend=c("Words1-4", "Word5"),  fill=c("red", "blue"))

如果您打算在 R 中生成大量图表,那么花时间学习使用 ggplot (ggplot2) 包可能是值得的。虽然有一点学习曲线,但它更加灵活,可以让您创建非常专业的图形。

这是一个使用 ggplot 的解决方案。

df <- data.frame(
    word1 = c(sample(LETTERS[1:5], 10, replace = T)),
    word2 = c(sample(LETTERS[1:5], 10, replace = T)),
    word3 = c(sample(LETTERS[1:5], 10, replace = T)),
    word4 = c(sample(LETTERS[1:5], 10, replace = T)),
    word5 = c(sample(LETTERS[1:5], 10, replace = T)),
    dur1 = c(round(abs(rnorm(10)),2)),
    dur2 = c(round(abs(rnorm(10)),2)),
    dur3 = c(round(abs(rnorm(10)),2)),
    dur4 = c(round(abs(rnorm(10)),2)),
    dur5 = c(round(abs(rnorm(10)),2))
)
df
# convert words to character:
df[,1:5] <- lapply(df[,1:5], as.character)
targets <- c("A", "C", "E")
word1to4 <- c(df$word1[df$word1 %in% targets], df$word2[df$word2 %in% targets], df$word3[df$word3 %in% targets],
              df$word4[df$word4 %in% targets])
dur1to4 <- c(df$dur1[df$word1 %in% targets], df$dur2[df$word2 %in% targets], df$dur3[df$word3 %in% targets],
             df$dur4[df$word4 %in% targets])

word5 <- df$word5[df$word5 %in% targets]
dur5 <- df$dur5[df$word5 %in% targets]

# Create Dataset to plot
library(ggplot2)

box_data<-data.frame(words=c(word1to4,word5),dur=c(dur1to4,dur5),
                     type=c(rep("1 to 4",length(word1to4)),rep("5",length(word5))))

box_data$type<-as.factor(box_data$type)
box_data$x<-interaction(box_data$words, box_data$type)

box_data$xc<-as.character(box_data$x)
box_data<-box_data[order(box_data$xc),]
box_data
my_boxplot<-ggplot(box_data, aes(x=xc, y=dur)) + geom_boxplot(aes(fill=type)) +
theme(legend.position = "top", legend.title = element_blank(), plot.title = element_text(hjust = 0.5)) +
ggtitle("Duration By Word and Type")

my_boxplot