ggplot2 パッケージで作成しているバイオリン プロットの幅を変更したいと考えています。
背景は次のとおりです。粒子の特定のサイズの観測数をカウントするデータセットを取得します。このサイズは私の y 変数、つまり「インシデント」と呼ぶインシデントの数になります。
データを単純化したので、1 つのデータ フレームに溶け込んだ 2 つの異なるセット (「id」で示される) のみを見ています。
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 軸をサイズにしたいので、「インシデント」列を含まず、代わりに「インシデント」の値に応じて新しい行を含むデータ フレームが必要です。
これを簡単に再形成する方法がわからなかったので、現在の反復で新しいデータ フレーム (dt2) に追加する必要がある行の種類を確認するために、カウンター変数と if 句を使用して for ループを実行しています。
次に、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()
ここまでは良いのですが、これはまさに私が望んでいるものではありません。特定のサイズの粒子の数ではなく、バイオリン プロットで、この特定のサイズのすべての粒子の全体的な体積を取得したいと考えています。つまり、バイオリンの幅は、カウント (つまり、dt1 の「インシデント」値または dt2 の特定のパラメーターを持つ行数) とサイズ自体の関数である必要があります。つまり、バイオリンの幅を y 値を高くして広くしたいということです。
たとえば、粒子の球形を考慮すると、サイズ 10 の「インシデント」値が 7 の場合、幅は 7 * (4/3 * pi * (10/2)^3) になります。ただし、サイズが 50 のパーティクルの場合、同じ「インシデント」値は、計算された幅が 7 * (4/3 * pi * (50/2)^3) になるはずです。
y 変数の関数として geom_violin プロットの幅計算を変更する方法はありますか? 残念ながら、サイズが 100 を超え、「インシデント」値が 1000 を超える粒子の行数が到達するため、ボリュームの数式を考慮するようにデータ フレームを実際に変更することはできません (つまり、「インシデント」に球状ボリュームの数式を掛けます)。天文学的な高さ (私のデータでは ~10,000,000,000 行のデータ フレームになります)。
どんなアイデアでも大歓迎です。
前もって感謝します!