2016-09-02 7 views
1

調査データを使って作業しています。調査項目には2つのグループがあり、各グループには3つの項目があります。私の調査サンプルには2人の回答者がいます。ggplot2でRの 'heatmap plotとsave'ループをうまく実装する方法

私は、調査項目のグループによってヒートマップを生成しようとしています:

  • 回答者は、彼らが「X」軸上にあるために応答した
  • 調査項目軸「Y」にあります。ここで

完全に再現可能な例である:私は私のコードを実行すると

wd <- "D:/Desktop/" 
    setwd(wd) 

    #--create dataframe 

    respondent = c("Respondent_1", "Respondent_1", "Respondent_1","Respondent_1", "Respondent_1", "Respondent_1", 
        "Respondent_2", "Respondent_2", "Respondent_2","Respondent_2", "Respondent_2", "Respondent_2") 
    item = c("Item_1", "Item_2", "Item_3","Item_1", "Item_2", "Item_3", 
      "Item_1", "Item_2", "Item_3","Item_1", "Item_2", "Item_3") 

    item_group = c("Group_1","Group_1","Group_1","Group_2","Group_2","Group_2", 
        "Group_1","Group_1","Group_1","Group_2","Group_2","Group_2") 
    score = c(1, 40, 100, 100, 30, 12, 
       2, 15, 80, 77, 44, 10) 

    high_value_color = c("darkred", "darkred", "darkred", 
         "brown3", "brown3", "brown3") 

    plot_df = data.frame(respondent, item, item_group, score, high_value_color) 

    #--write function 
    #--inspired from this: http://www.reed.edu/data-at-reed/resources/R/loops_with_ggplot2.html 

    plot_list <- unique(plot_df$item_group) 

    survey_items.graph <- function(df, na.rm = TRUE, ...) { 

    #--loop to generate heatmaps for each group 

     for (i in seq_along(plot_list)) { 

     plot <- ggplot(aes(x = df$item[df$item_group == plot_list[i]], 
          y = df$respondent[df$item_group==plot_list[i]]), 
         data = subset(df, df$item_group == plot_list[i])) + 
      geom_tile(aes(fill = df$score[df$item_group == plot_list[i]]), colour = "black") + 
      scale_fill_gradient2(low = "azure1", 
           high = df$high_value_color[df$item_group == plot_list[i]], 
           guide = "colorbar") + 
      geom_text(aes(label = df$score[df$item_group==plot_list[i]], 
         hjust = 0.5, 
         angle = 90), 
         size = 4) + 
      ggtitle(df$item_group[df$item_group==plot_list[i]]) + 
      theme(panel.grid.major = element_blank(), 
       panel.grid.minor = element_blank(), 
       panel.background = element_blank(), 
       plot.title = element_text(size = 7, face="bold"), 
       axis.text.y = element_text(size = 7, face ="bold"), 
       axis.text.x = element_text(angle=90, hjust=1), 
       axis.title = element_blank(), 
       legend.position = "none") 
     # save plots as .png 
     ggsave(plot, file=paste(wd,"plots/heatmap for ", plot_list[i], ".png", sep=""), scale=2) 
     print(plot) 
     } 
    } 

    #--load ggplot2 

    library(ggplot2) 

    #--execute function on plot dataframe 
    survey_items.graph(plot_df) 

、私は、次の2つのプロットを得た:

current plots

を私の直感は、私はことを私に伝えます私のコードの 'scale_fill_gradient2'部分の 'high'引数で何か正しいことをしないでください。

テストでは、 'high'引数を許容可能なカラー文字列値(たとえば 'brown3'、他の色はhere)に置き換えたとき、プロットはI彼らに欲しい。

tweaked plots

は、私が欲しいのは、データのhigh_value_color 『変数で見つかった値が』対応する項目を受け入れるための「scale_fill_gradient2」の「高」引数のためです。

+1

まず、 'aes()'呼び出しから 'df $'を削除します。 – Axeman

+0

あなたの直感は正しいです。 'scale_fill_gradient2'の' high'引数に6色を渡しています。 – Axeman

+3

あなたはサブセットdf $ item_group == plot_list [i]] 'を使って自分自身を非常にたくさん繰り返しています。 'for'ループの最初の行を' sub_df = df [df $ item_group == plot_list [i]]] 'にして、それを使うたびにすべてのデータ要素をサブセット化するのではなく' sub_df'を使います。 – Gregor

答えて

3

主な問題は、色をscale_fill_gradient2に渡すことでした。しかし、あなたのコードには改善の余地があります。具体的には、裸の変数名をaesに渡すだけです。私はまたあなたがいつもあなたの部分集合を何度も繰り返す理由を見ません。あなたは自分自身が困ってしまう可能性が非常に高いです。ここで

は、私はおそらく、このような問題に取り組むだろうかです:すべての

まず、私たちはずっと簡単な関数を作る:それだけで直接データの引数を取り、単にそのデータで必要なプロットを作ります(ループなし)。

survey_items.graph <- function(dat) { 
    ggplot(aes(x = item, y = respondent), data = dat) + 
    geom_tile(aes(fill = score), colour = "black") + 
    scale_fill_gradient2(low = "azure1", 
         high = dat$high_value_color[1], 
         guide = "colorbar") + 
    geom_text(aes(label = score), hjust = 0.5, angle = 90, size = 4) + 
    ggtitle(dat$item_group[1]) + 
    theme(panel.grid.major = element_blank(), 
      panel.grid.minor = element_blank(), 
      panel.background = element_blank(), 
      plot.title = element_text(size = 7, face="bold"), 
      axis.text.y = element_text(size = 7, face ="bold"), 
      axis.text.x = element_text(angle=90, hjust=1), 
      axis.title = element_blank(), 
      legend.position = "none") 
} 

次に、splitのデータをデータのリストに追加します。フレーム、item_groupあたり1:

split_data <- split(plot_df, plot_df$item_group) 

その後、我々は、プロットのリストを作成し、リスト内の各エントリに、当社の機能を適用します。

plot_list <- lapply(split_data, survey_items.graph) 

便宜上、ここで、私はすぐに両方のプロットをステッチするgrid.arrangeを使用一緒:

:私はあなたがそれらを保存したい

library(gridExtra) 
do.call(grid.arrange, plot_list) 

次のようなものを使用することができます

Map(function(x, i, ...) ggsave(paste0('plot', i, '.png'), x, ...), 
    plot_list, seq_along(plot_list), scale = 2) 

enter image description here

+0

Hey。@aosmithのコメントは私の現在のアプローチのために働いています。 – ealfons1

+2

@ ealfons1もちろん、さまざまなアプローチがありますが、少なくともあなたの 'aes'呼び出しを修正してください。あなたの道は遅かれ早かれあなたを後ろから噛みます!良い週末を過ごしてください。 – Axeman

+1

'aes()'の中の '$'は単純なggplotsで動作しますが、悪い習慣です。ファセットや複雑なstat関数が含まれていると破損します* – Gregor

関連する問題