LoginSignup
pyotr
@pyotr

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

グラフが格納された、リストの入れ子を解消したい

Q&AClosed

入れ子のforループでグラフを複数出力したものを、grid.arrange()か何かで並べたい

irisを例にして状況を説明します。
もっと良いR上で元から使えるデータがあるかもしれませんが、iris以外をあまり知らないのでご容赦ください。

irisは3品種*50行の150行となっています。
ここで、それぞれの品種につきa,b,cという産地があるという想定にします(同じ品種setotaでも、a,b,cの産地がある)。

production.area=rep(c("a","b","c"), times=50 )
iris=cbind(iris, production.area)

このデータに対して、品種と産地ごとに何かしらのプロットをしたいとします。
つまり、3品種3産地で、9枚のプロットをまとめたものを作ることが目標です。

そこで書いたのが以下のようなものです。

plotlist=NULL
for(i in unique(iris$Species)){
  for(j in unique(iris$production.area)){
    (plotlist[[i]][[j]]=iris %>%
       filter(Species==i)%>%
       filter(production.area==j)%>%
       ggplot(aes(x=Sepal.Length, y=Sepal.Width))+
       geom_point()+
       labs(title=paste0(i,"*",j))
     )
  }
}

これに関しては、
https://indenkun.hatenablog.com/entry/2021/11/12/122044
こちらのブログを参考にさせていただいております。

しかし、この場合グラフを格納したリストが入れ子構造になってしまっているので、

grid.arrange(grobs=plotlist)

とすることはできません。なお、grid.arrange()に強いこだわりがある訳ではありません。

これに対する解決策は、
①forループの段階で入れ子にならないようにする
②後からリストの入れ子を解消する
③リストに格納せずにprint()し、par()で並べる
が思いつくものです。

想定している状況の趣旨としては①か②のものを教えていただきたいのですが、③についてもfor文でグラフを書いているときにどこにpar()を挟めば良いのか分からないので、その点についても教えていただけると大変助かります。

なお、質問者のバックグラウンドはRについて碌に分からないまま進めた卒論がひと段落し、力技で処理していた部分から疑問点を切り出して質問させていただいている状況です。初歩的な質問で申し訳ありませんが、よろしくお願いいたします。

0

1Answer

①forループの段階で入れ子にならないようにする

の方法です。
コメントの通りですが、もとの形では plotlist[Species][production.area] という形になっているので、それを plotlist[Species"*"production.area] という形の入れ子ではない状態で保存しています。

plotlist=NULL
for(i in unique(iris$Species)){
  for(j in unique(iris$production.area)){
+    # [[paste(i, j, sep="*")]] とすることで
+    # Species*production.area の名前で1次元配列として保存する 
+    (plotlist[[paste(i, j, sep="*")]]=iris %>% 
-    (plotlist[[i]][[j]]=iris %>%
       filter(Species==i) %>% 
       filter(production.area==j) %>% 
       ggplot(aes(x=Sepal.Length, y=Sepal.Width))+
       geom_point()+
       labs(title=paste0(i,"*",j))
    )
  }
}
grid.arrange(grobs=plotlist)

③リストに格納せずにprint()し、par()で並べる

について、R のグラフ描画システムとして graphics と grid が存在し、par() は前者の上に、 ggplot2 は後者の上に成り立っています。
なので ggplot2 で描画している以上は par() で並べることは難しいのではないかなと思っています。

0

Comments

  1. @pyotr

    Questioner

    返信遅れました。大変参考になりました、ありがとうございます。

Your answer might help someone💌