我想修改我用ggplot2包构建的小提琴图的宽度。
背景如下:我得到一个数据集,它可以计算特定粒子大小的观察数量。这个大小将是我的y变量,我将调用的事件数"事件"。
我简化了数据,因此我只查看了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轴是大小,我需要有一个数据框,其中不再包含&#34;事件&#34;列,而是使用新行,具体取决于&#34;事件&#34;。
的值我无法弄清楚如何更轻松地重塑这个,所以我运行一个带有计数器变量的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()
到目前为止一切顺利,但这并不是我想要的。我想要小提琴图给我具有这个特定尺寸的所有粒子的总体积,而不是具有特定尺寸的粒子数。即小提琴的宽度应该是计数的函数(因此&#34;事件&#34; dt1的值或具有特定参数dt2的行数)和大小本身。这意味着我希望小提琴变得更宽,y值更高。
考虑例如一个球形的颗粒,一个&#34;事件&#34;对于10的大小,值7应该给出7 *(4/3 * pi *(10/2)^ 3)的宽度。然而,对于尺寸为50的颗粒,相同的&#34;事件&#34;值应导致计算宽度为7 *(4/3 * pi *(50/2)^ 3)。
有没有办法改变geom_violin图的宽度计算作为y变量的函数?遗憾的是,我无法真正改变数据框以考虑体积的数学公式(即乘以&#34;事件&#34;用球形体积公式),因为粒子大小的行数&gt; 100和&#34;事件&#34; - 值&gt; 1000达到天文高度(对于我的数据,将产生具有~100,000,000,000行的数据帧)。
非常感谢任何想法。
提前致谢!