R - 根据 y 变量修改 (ggplot) 小提琴图的宽度

R - Modify the width of (ggplot) violin plots as a function of the y-variable

我想修改我用 ggplot2 包构建的小提琴图的宽度。

背景如下:我得到了一个数据集,该数据集计算了特定大小粒子的多个观测值。这个大小将是我的 y 变量,我将调用的事件计数 "incidents".

我简化了数据,所以我只查看 2 个不同的集合(由 "id" 表示),融入 1 个数据框。

library(ggplot2)
library(data.table)
dt1 <- data.frame(id=c("A","A","A","A","A","B","B","B","B","B"),y=c(10,20,30,40,50,10,20,30,40,50),incidents=c(3,1,5,9,2,4,2,7,1,5))

据我所知,小提琴图是根据特定值的出现次数计算小提琴的宽度。因为我希望绘图的 y 轴是大小,所以我需要一个数据框,其中不再包含 "incidents" 列,而是包含新行,具体取决于 "incidents" 的值.

我不知道如何更容易地重塑它,所以我 运行 一个带有计数器变量的 for 循环和一个 if 子句,用于检查当前迭代必须添加到新的行的类型数据框 (dt2).

然后我使用 geom_violin() 绘制 ggplot 包。

library(ggplot2)
library(data.table)
dt1 <- data.frame(id=c("A","A","A","A","A","B","B","B","B","B"),y=c(10,20,30,40,50,10,20,30,40,50),incidents=c(3,1,5,9,2,4,2,7,1,5))

newlength <- sum(dt1$incidents) #This is the length of the new data table
dt2 <- data.table(id=rep(as.character(0),newlength),size=rep(0,newlength))
counter <- 1 #initialize
for (i in 1:newlength){ #iterate through all rows of new data table
if (i > sum(dt1$incidents[1:counter])){ #check if current iteration number is larger than the accumulated number of all incidents that have been checked so far in dt1
counter <- counter+1 #if so, increase counter
}
dt2[i,1:2 :=dt1[counter,c(1,2)]] #add the id and size information that is stored in dt1 at the row currently looked at
}

p <- ggplot(dt2, aes(x=1,y=size,color=id))
p + geom_violin()

到目前为止一切顺利,但这并不是我想要的。我希望小提琴图给出 具有该特定大小的所有粒子的总体积 ,而不是特定大小的粒子数。 IE。小提琴的宽度应该是计数(因此 dt1 的 "incidents" 值或具有 dt2 特定参数的行数)和大小本身的函数。这意味着我希望小提琴随着 y 值的增加而变得更宽。

考虑例如球形粒子,"incidents" 值为 7,大小为 10 时,宽度应为 7 * (4/3 * pi * (10/2)^3)。然而,对于大小为 50 的粒子,相同的 "incidents" 值应导致计算出的宽度为 7 * (4/3 * pi * (50/2)^3).

有什么方法可以根据 y 变量更改 geom_violin 图的宽度计算?不幸的是,我无法真正更改数据框以考虑体积的数学公式(即,将 "incidents" 与球形体积公式相乘),因为尺寸 > 100 和 "incidents"- 的粒子的行数> 1000 的值达到了天文高度(将导致我的数据包含约 10,000,000,000 行的数据框)。

非常感谢任何想法。

提前致谢!

首先计算新变量:

dt1$total_particle_size<-dt1$incidents * (4/3 * pi * (dt1$y/2)^3)

然后剧情:

ggplot(dt1, aes(x=id,y=y,fill=id,width=total_particle_size))+
 geom_violin()

我确实收到了一条警告,您可能需要检查一下。