使用stat_summary在图表中注释观测值数量。

18
我如何使用stat_summary在图表上标注n = x,其中x是一个变量?下面是所需输出的示例:

enter image description here

我可以通过以下相对低效的代码制作上述图表:
nlabels <- sapply(1:length(unique(mtcars$cyl)), function(i) as.vector(t(as.data.frame(table(mtcars$cyl))[,2][[i]])))
ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
  geom_boxplot(fill = "grey80", colour = "#3366FF") + 
  geom_text(aes(x = 1, y = median(mtcars$mpg[mtcars$cyl==sort(unique(mtcars$cyl))[1]]), label = paste0("n = ",nlabels[[1]]) )) +
  geom_text(aes(x = 2, y = median(mtcars$mpg[mtcars$cyl==sort(unique(mtcars$cyl))[2]]), label = paste0("n = ",nlabels[[2]]) )) +
  geom_text(aes(x = 3, y = median(mtcars$mpg[mtcars$cyl==sort(unique(mtcars$cyl))[3]]), label = paste0("n = ",nlabels[[3]]) )) 

这是对于这个问题的后续:如何在ggplot2 boxplot中添加每个组的观测次数并使用组平均值?。我可以使用stat_summary计算和显示观测次数,但我无法找到一种方法在stat_summary输出中包括n =。似乎stat_summary可能是这种标记的最有效方法,但其他方法也可以接受。
2个回答

36

您可以创建自己的函数并在stat_summary()内使用。这里的n_fun计算y值的位置,例如median(),然后添加label=,其中包括n=和观测值的数量。使用data.frame()而不是c()很重要,因为paste0()会产生字符,但y值是数值,而c()会使两者都变成字符。然后,在stat_summary()中使用此函数和geom="text"。这将确保为每个x值位置和标签仅从该级别的数据中制作。

n_fun <- function(x){
  return(data.frame(y = median(x), label = paste0("n = ",length(x))))
}

ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
  geom_boxplot(fill = "grey80", colour = "#3366FF") + 
  stat_summary(fun.data = n_fun, geom = "text")

输入图像描述


太好了,谢谢。我在函数中卡住了return(c(y = ...,你的答案表明return(data.frame(y = ...是正确的方法。 - Ben
@DidzisElferts,这个标签是否可以扩展以适应上面的躲避版本标签?类似于aes(fill = factor(vs)) - Paulo E. Cardoso
在标签字符串末尾添加"\n"将导致文本打印在该行的正上方(对于单色绘图很有用)。例如,return(data.frame(y = median(x), label = paste0(paste0("n = ",length(x)),"\n"))) - Fuhrmanator

12

大多数R中的东西都是向量化的,因此您可以利用它。

nlabels <- table(mtcars$cyl)

#  To create the median labels, you can use by
meds <- c(by(mtcars$mpg, mtcars$cyl, median))

ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
   geom_boxplot(fill = "grey80", colour = "#3366FF") + 
   geom_text(data = data.frame(), aes(x = names(meds) , y = meds, 
            label = paste("n =", nlabels)))

boxplot


关于nlables

您可以简单地使用以下语句,而不是您的sapply语句:

nlabels <- table(mtcars$cyl)

请注意,您当前的代码正在对上述内容进行转换、转置,然后仅迭代每一行以逐个抓取值,然后将它们重新组合成单个向量。

如果您确实希望将它们作为未定义尺寸的整数向量,请使用c()

nlabels <- c(table(mtcars$cyl))   

当然,即使这样也不需要实现上述目标。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接