Adding group-specific text/data to faceted plot in R/ggplot2










3















I am comparing the intra-group correlation between duplicate samples within a large gene expression experiment, where I have multiple separate biological groups - the idea being to see if any of the groups is much less well-correlated than the others, indicating a potential sample mixup or other error.



I am using ggplot to plot the expression values of each duplicate pair against each other. I would like to also be able to add the correlation coefficient and p-value to each panel of the plot, which I obtain through summarize and cor.test. You can use this code to get the general idea: in exp1, the duplicates are correlated, but not in exp2.



library(tidyverse)

df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))
head(df)
tail(df)

df %>% ggplot(aes(x=a, y=b))+
geom_point() +
facet_wrap(~exp)

group_by(df, exp) %>%
summarize(corr=cor.test(a,b)$estimate, pval=cor.test(a,b)$p.value)


This is the plot I generated via ggplot, and I've manually added the R and p-values that I got at the end. But of course, if I have a lot of sample pairs to analyze, it would be nice to be able to add these automatically from within the ggplot call. I'm just not sure how to do it.



enter image description here










share|improve this question




























    3















    I am comparing the intra-group correlation between duplicate samples within a large gene expression experiment, where I have multiple separate biological groups - the idea being to see if any of the groups is much less well-correlated than the others, indicating a potential sample mixup or other error.



    I am using ggplot to plot the expression values of each duplicate pair against each other. I would like to also be able to add the correlation coefficient and p-value to each panel of the plot, which I obtain through summarize and cor.test. You can use this code to get the general idea: in exp1, the duplicates are correlated, but not in exp2.



    library(tidyverse)

    df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
    df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))
    head(df)
    tail(df)

    df %>% ggplot(aes(x=a, y=b))+
    geom_point() +
    facet_wrap(~exp)

    group_by(df, exp) %>%
    summarize(corr=cor.test(a,b)$estimate, pval=cor.test(a,b)$p.value)


    This is the plot I generated via ggplot, and I've manually added the R and p-values that I got at the end. But of course, if I have a lot of sample pairs to analyze, it would be nice to be able to add these automatically from within the ggplot call. I'm just not sure how to do it.



    enter image description here










    share|improve this question


























      3












      3








      3


      1






      I am comparing the intra-group correlation between duplicate samples within a large gene expression experiment, where I have multiple separate biological groups - the idea being to see if any of the groups is much less well-correlated than the others, indicating a potential sample mixup or other error.



      I am using ggplot to plot the expression values of each duplicate pair against each other. I would like to also be able to add the correlation coefficient and p-value to each panel of the plot, which I obtain through summarize and cor.test. You can use this code to get the general idea: in exp1, the duplicates are correlated, but not in exp2.



      library(tidyverse)

      df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
      df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))
      head(df)
      tail(df)

      df %>% ggplot(aes(x=a, y=b))+
      geom_point() +
      facet_wrap(~exp)

      group_by(df, exp) %>%
      summarize(corr=cor.test(a,b)$estimate, pval=cor.test(a,b)$p.value)


      This is the plot I generated via ggplot, and I've manually added the R and p-values that I got at the end. But of course, if I have a lot of sample pairs to analyze, it would be nice to be able to add these automatically from within the ggplot call. I'm just not sure how to do it.



      enter image description here










      share|improve this question
















      I am comparing the intra-group correlation between duplicate samples within a large gene expression experiment, where I have multiple separate biological groups - the idea being to see if any of the groups is much less well-correlated than the others, indicating a potential sample mixup or other error.



      I am using ggplot to plot the expression values of each duplicate pair against each other. I would like to also be able to add the correlation coefficient and p-value to each panel of the plot, which I obtain through summarize and cor.test. You can use this code to get the general idea: in exp1, the duplicates are correlated, but not in exp2.



      library(tidyverse)

      df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
      df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))
      head(df)
      tail(df)

      df %>% ggplot(aes(x=a, y=b))+
      geom_point() +
      facet_wrap(~exp)

      group_by(df, exp) %>%
      summarize(corr=cor.test(a,b)$estimate, pval=cor.test(a,b)$p.value)


      This is the plot I generated via ggplot, and I've manually added the R and p-values that I got at the end. But of course, if I have a lot of sample pairs to analyze, it would be nice to be able to add these automatically from within the ggplot call. I'm just not sure how to do it.



      enter image description here







      r ggplot2






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 15 '18 at 5:29







      C. Murtaugh

















      asked Nov 15 '18 at 1:34









      C. MurtaughC. Murtaugh

      647




      647






















          3 Answers
          3






          active

          oldest

          votes


















          3














          We can use the stat_cor function from the ggpubr package.



          set.seed(123)

          library(dplyr)
          library(ggplot2)
          library(ggpubr)

          df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
          df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))

          ggplot(df, aes(x=a, y=b))+
          geom_point() +
          facet_wrap(~exp) +
          stat_cor(method = "pearson")


          enter image description here






          share|improve this answer























          • This worked perfectly, thank you very much. This is what my final plot with R2 values looks like - exactly what I was hoping to generate: imgur.com/a/v8T6zu3

            – C. Murtaugh
            Nov 15 '18 at 5:47



















          4














          If, for whatever reason, you want to build this yourself instead of using the ggpubr functions, you can create your summary data, format labels, and place the labels with geom_text.



          I'm formatting the stats so that R has a fixed 3 significant digits and p has 3 digits, falling back on scientific notation. I changed the names of those columns in summarise to R and p to make the labels below. Reshaping to long data and creating a new column with unite gets this:





          library(tidyverse)
          ...

          group_by(df, exp) %>%
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ")
          #> # A tibble: 4 x 2
          #> exp stat
          #> <chr> <chr>
          #> 1 exp1 R = 0.965
          #> 2 exp2 R = 0.0438
          #> 3 exp1 p = 1.14e-58
          #> 4 exp2 p = 0.665


          Then for each of the groups, I want to collapse both labels, separated by a newline n. This is a place that will scale well—you might have more summary stats to display, but this should still work.



          summ <- group_by(df, exp) %>% 
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ") %>%
          group_by(exp) %>%
          summarise(both_stats = paste(stat, collapse = "n"))

          summ
          #> # A tibble: 2 x 2
          #> exp both_stats
          #> <chr> <chr>
          #> 1 exp1 "R = 0.965np = 1.14e-58"
          #> 2 exp2 "R = 0.0438np = 0.665"


          In geom_text, I'm setting the x coordinate to -Inf, which gets the minimum of all x values, and the y coordinate as Inf for the maximum of all y values. That puts the label in the top-left corner, regardless of the values in the data.



          The one thing I don't like here is then hacking the hjust and vjust outside their intended ranges of 0 to 1. But nudge_x/nudge_y won't do anything because of the values being set to infinity.



          df %>% 
          ggplot(aes(x = a, y = b)) +
          geom_point() +
          geom_text(aes(x = -Inf, y = Inf, label = both_stats), data = summ,
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~ exp)




          Created on 2018-11-14 by the reprex package (v0.2.1)






          share|improve this answer























          • Thanks for the detailed code breakdown - the ggpubr method is easy to carry out but it's hard to figure out exactly how it works. I appreciate that I can figure out how to tinker with your method.

            – C. Murtaugh
            Nov 15 '18 at 5:45


















          3














          Similar to the answer of camille, but you can do all in one run



          library(tidyverse)
          set.seed(123)
          df %>%
          group_by(exp) %>%
          mutate(p = cor.test(a, b)$p.value,
          rho = cor.test(a, b)$estimate) %>%
          mutate_at(vars(p, rho), signif, 2) %>%
          ggplot(aes(x=a, y=b)) +
          geom_point() +
          geom_text(data = . %>% distinct(p, rho, exp),
          aes(x = -Inf, y = Inf,label = paste("p=",p,"nrho=",rho)),
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~exp)


          enter image description here






          share|improve this answer























          • Very nice - I would not have thought of using distinct like that but it totally makes sense.

            – C. Murtaugh
            Nov 15 '18 at 16:41










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53311214%2fadding-group-specific-text-data-to-faceted-plot-in-r-ggplot2%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          We can use the stat_cor function from the ggpubr package.



          set.seed(123)

          library(dplyr)
          library(ggplot2)
          library(ggpubr)

          df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
          df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))

          ggplot(df, aes(x=a, y=b))+
          geom_point() +
          facet_wrap(~exp) +
          stat_cor(method = "pearson")


          enter image description here






          share|improve this answer























          • This worked perfectly, thank you very much. This is what my final plot with R2 values looks like - exactly what I was hoping to generate: imgur.com/a/v8T6zu3

            – C. Murtaugh
            Nov 15 '18 at 5:47
















          3














          We can use the stat_cor function from the ggpubr package.



          set.seed(123)

          library(dplyr)
          library(ggplot2)
          library(ggpubr)

          df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
          df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))

          ggplot(df, aes(x=a, y=b))+
          geom_point() +
          facet_wrap(~exp) +
          stat_cor(method = "pearson")


          enter image description here






          share|improve this answer























          • This worked perfectly, thank you very much. This is what my final plot with R2 values looks like - exactly what I was hoping to generate: imgur.com/a/v8T6zu3

            – C. Murtaugh
            Nov 15 '18 at 5:47














          3












          3








          3







          We can use the stat_cor function from the ggpubr package.



          set.seed(123)

          library(dplyr)
          library(ggplot2)
          library(ggpubr)

          df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
          df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))

          ggplot(df, aes(x=a, y=b))+
          geom_point() +
          facet_wrap(~exp) +
          stat_cor(method = "pearson")


          enter image description here






          share|improve this answer













          We can use the stat_cor function from the ggpubr package.



          set.seed(123)

          library(dplyr)
          library(ggplot2)
          library(ggpubr)

          df <- data.frame(exp=c(rep('exp1', 100), rep('exp2', 100)), a=rnorm(200, 1000, 200))
          df <- mutate(df, b=ifelse(exp=='exp1', a*rnorm(100,1,0.05), rnorm(100, 1000, 200)))

          ggplot(df, aes(x=a, y=b))+
          geom_point() +
          facet_wrap(~exp) +
          stat_cor(method = "pearson")


          enter image description here







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 15 '18 at 1:51









          wwwwww

          27.9k112341




          27.9k112341












          • This worked perfectly, thank you very much. This is what my final plot with R2 values looks like - exactly what I was hoping to generate: imgur.com/a/v8T6zu3

            – C. Murtaugh
            Nov 15 '18 at 5:47


















          • This worked perfectly, thank you very much. This is what my final plot with R2 values looks like - exactly what I was hoping to generate: imgur.com/a/v8T6zu3

            – C. Murtaugh
            Nov 15 '18 at 5:47

















          This worked perfectly, thank you very much. This is what my final plot with R2 values looks like - exactly what I was hoping to generate: imgur.com/a/v8T6zu3

          – C. Murtaugh
          Nov 15 '18 at 5:47






          This worked perfectly, thank you very much. This is what my final plot with R2 values looks like - exactly what I was hoping to generate: imgur.com/a/v8T6zu3

          – C. Murtaugh
          Nov 15 '18 at 5:47














          4














          If, for whatever reason, you want to build this yourself instead of using the ggpubr functions, you can create your summary data, format labels, and place the labels with geom_text.



          I'm formatting the stats so that R has a fixed 3 significant digits and p has 3 digits, falling back on scientific notation. I changed the names of those columns in summarise to R and p to make the labels below. Reshaping to long data and creating a new column with unite gets this:





          library(tidyverse)
          ...

          group_by(df, exp) %>%
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ")
          #> # A tibble: 4 x 2
          #> exp stat
          #> <chr> <chr>
          #> 1 exp1 R = 0.965
          #> 2 exp2 R = 0.0438
          #> 3 exp1 p = 1.14e-58
          #> 4 exp2 p = 0.665


          Then for each of the groups, I want to collapse both labels, separated by a newline n. This is a place that will scale well—you might have more summary stats to display, but this should still work.



          summ <- group_by(df, exp) %>% 
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ") %>%
          group_by(exp) %>%
          summarise(both_stats = paste(stat, collapse = "n"))

          summ
          #> # A tibble: 2 x 2
          #> exp both_stats
          #> <chr> <chr>
          #> 1 exp1 "R = 0.965np = 1.14e-58"
          #> 2 exp2 "R = 0.0438np = 0.665"


          In geom_text, I'm setting the x coordinate to -Inf, which gets the minimum of all x values, and the y coordinate as Inf for the maximum of all y values. That puts the label in the top-left corner, regardless of the values in the data.



          The one thing I don't like here is then hacking the hjust and vjust outside their intended ranges of 0 to 1. But nudge_x/nudge_y won't do anything because of the values being set to infinity.



          df %>% 
          ggplot(aes(x = a, y = b)) +
          geom_point() +
          geom_text(aes(x = -Inf, y = Inf, label = both_stats), data = summ,
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~ exp)




          Created on 2018-11-14 by the reprex package (v0.2.1)






          share|improve this answer























          • Thanks for the detailed code breakdown - the ggpubr method is easy to carry out but it's hard to figure out exactly how it works. I appreciate that I can figure out how to tinker with your method.

            – C. Murtaugh
            Nov 15 '18 at 5:45















          4














          If, for whatever reason, you want to build this yourself instead of using the ggpubr functions, you can create your summary data, format labels, and place the labels with geom_text.



          I'm formatting the stats so that R has a fixed 3 significant digits and p has 3 digits, falling back on scientific notation. I changed the names of those columns in summarise to R and p to make the labels below. Reshaping to long data and creating a new column with unite gets this:





          library(tidyverse)
          ...

          group_by(df, exp) %>%
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ")
          #> # A tibble: 4 x 2
          #> exp stat
          #> <chr> <chr>
          #> 1 exp1 R = 0.965
          #> 2 exp2 R = 0.0438
          #> 3 exp1 p = 1.14e-58
          #> 4 exp2 p = 0.665


          Then for each of the groups, I want to collapse both labels, separated by a newline n. This is a place that will scale well—you might have more summary stats to display, but this should still work.



          summ <- group_by(df, exp) %>% 
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ") %>%
          group_by(exp) %>%
          summarise(both_stats = paste(stat, collapse = "n"))

          summ
          #> # A tibble: 2 x 2
          #> exp both_stats
          #> <chr> <chr>
          #> 1 exp1 "R = 0.965np = 1.14e-58"
          #> 2 exp2 "R = 0.0438np = 0.665"


          In geom_text, I'm setting the x coordinate to -Inf, which gets the minimum of all x values, and the y coordinate as Inf for the maximum of all y values. That puts the label in the top-left corner, regardless of the values in the data.



          The one thing I don't like here is then hacking the hjust and vjust outside their intended ranges of 0 to 1. But nudge_x/nudge_y won't do anything because of the values being set to infinity.



          df %>% 
          ggplot(aes(x = a, y = b)) +
          geom_point() +
          geom_text(aes(x = -Inf, y = Inf, label = both_stats), data = summ,
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~ exp)




          Created on 2018-11-14 by the reprex package (v0.2.1)






          share|improve this answer























          • Thanks for the detailed code breakdown - the ggpubr method is easy to carry out but it's hard to figure out exactly how it works. I appreciate that I can figure out how to tinker with your method.

            – C. Murtaugh
            Nov 15 '18 at 5:45













          4












          4








          4







          If, for whatever reason, you want to build this yourself instead of using the ggpubr functions, you can create your summary data, format labels, and place the labels with geom_text.



          I'm formatting the stats so that R has a fixed 3 significant digits and p has 3 digits, falling back on scientific notation. I changed the names of those columns in summarise to R and p to make the labels below. Reshaping to long data and creating a new column with unite gets this:





          library(tidyverse)
          ...

          group_by(df, exp) %>%
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ")
          #> # A tibble: 4 x 2
          #> exp stat
          #> <chr> <chr>
          #> 1 exp1 R = 0.965
          #> 2 exp2 R = 0.0438
          #> 3 exp1 p = 1.14e-58
          #> 4 exp2 p = 0.665


          Then for each of the groups, I want to collapse both labels, separated by a newline n. This is a place that will scale well—you might have more summary stats to display, but this should still work.



          summ <- group_by(df, exp) %>% 
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ") %>%
          group_by(exp) %>%
          summarise(both_stats = paste(stat, collapse = "n"))

          summ
          #> # A tibble: 2 x 2
          #> exp both_stats
          #> <chr> <chr>
          #> 1 exp1 "R = 0.965np = 1.14e-58"
          #> 2 exp2 "R = 0.0438np = 0.665"


          In geom_text, I'm setting the x coordinate to -Inf, which gets the minimum of all x values, and the y coordinate as Inf for the maximum of all y values. That puts the label in the top-left corner, regardless of the values in the data.



          The one thing I don't like here is then hacking the hjust and vjust outside their intended ranges of 0 to 1. But nudge_x/nudge_y won't do anything because of the values being set to infinity.



          df %>% 
          ggplot(aes(x = a, y = b)) +
          geom_point() +
          geom_text(aes(x = -Inf, y = Inf, label = both_stats), data = summ,
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~ exp)




          Created on 2018-11-14 by the reprex package (v0.2.1)






          share|improve this answer













          If, for whatever reason, you want to build this yourself instead of using the ggpubr functions, you can create your summary data, format labels, and place the labels with geom_text.



          I'm formatting the stats so that R has a fixed 3 significant digits and p has 3 digits, falling back on scientific notation. I changed the names of those columns in summarise to R and p to make the labels below. Reshaping to long data and creating a new column with unite gets this:





          library(tidyverse)
          ...

          group_by(df, exp) %>%
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ")
          #> # A tibble: 4 x 2
          #> exp stat
          #> <chr> <chr>
          #> 1 exp1 R = 0.965
          #> 2 exp2 R = 0.0438
          #> 3 exp1 p = 1.14e-58
          #> 4 exp2 p = 0.665


          Then for each of the groups, I want to collapse both labels, separated by a newline n. This is a place that will scale well—you might have more summary stats to display, but this should still work.



          summ <- group_by(df, exp) %>% 
          summarize(R = cor.test(a, b)$estimate, p = cor.test(a, b)$p.value) %>%
          mutate(R = formatC(R, format = "fg", digits = 3),
          p = formatC(p, format = "g", digits = 3)) %>%
          gather(key = measure, value = value, -exp) %>%
          unite("stat", measure, value, sep = " = ") %>%
          group_by(exp) %>%
          summarise(both_stats = paste(stat, collapse = "n"))

          summ
          #> # A tibble: 2 x 2
          #> exp both_stats
          #> <chr> <chr>
          #> 1 exp1 "R = 0.965np = 1.14e-58"
          #> 2 exp2 "R = 0.0438np = 0.665"


          In geom_text, I'm setting the x coordinate to -Inf, which gets the minimum of all x values, and the y coordinate as Inf for the maximum of all y values. That puts the label in the top-left corner, regardless of the values in the data.



          The one thing I don't like here is then hacking the hjust and vjust outside their intended ranges of 0 to 1. But nudge_x/nudge_y won't do anything because of the values being set to infinity.



          df %>% 
          ggplot(aes(x = a, y = b)) +
          geom_point() +
          geom_text(aes(x = -Inf, y = Inf, label = both_stats), data = summ,
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~ exp)




          Created on 2018-11-14 by the reprex package (v0.2.1)







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 15 '18 at 3:39









          camillecamille

          7,49531732




          7,49531732












          • Thanks for the detailed code breakdown - the ggpubr method is easy to carry out but it's hard to figure out exactly how it works. I appreciate that I can figure out how to tinker with your method.

            – C. Murtaugh
            Nov 15 '18 at 5:45

















          • Thanks for the detailed code breakdown - the ggpubr method is easy to carry out but it's hard to figure out exactly how it works. I appreciate that I can figure out how to tinker with your method.

            – C. Murtaugh
            Nov 15 '18 at 5:45
















          Thanks for the detailed code breakdown - the ggpubr method is easy to carry out but it's hard to figure out exactly how it works. I appreciate that I can figure out how to tinker with your method.

          – C. Murtaugh
          Nov 15 '18 at 5:45





          Thanks for the detailed code breakdown - the ggpubr method is easy to carry out but it's hard to figure out exactly how it works. I appreciate that I can figure out how to tinker with your method.

          – C. Murtaugh
          Nov 15 '18 at 5:45











          3














          Similar to the answer of camille, but you can do all in one run



          library(tidyverse)
          set.seed(123)
          df %>%
          group_by(exp) %>%
          mutate(p = cor.test(a, b)$p.value,
          rho = cor.test(a, b)$estimate) %>%
          mutate_at(vars(p, rho), signif, 2) %>%
          ggplot(aes(x=a, y=b)) +
          geom_point() +
          geom_text(data = . %>% distinct(p, rho, exp),
          aes(x = -Inf, y = Inf,label = paste("p=",p,"nrho=",rho)),
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~exp)


          enter image description here






          share|improve this answer























          • Very nice - I would not have thought of using distinct like that but it totally makes sense.

            – C. Murtaugh
            Nov 15 '18 at 16:41















          3














          Similar to the answer of camille, but you can do all in one run



          library(tidyverse)
          set.seed(123)
          df %>%
          group_by(exp) %>%
          mutate(p = cor.test(a, b)$p.value,
          rho = cor.test(a, b)$estimate) %>%
          mutate_at(vars(p, rho), signif, 2) %>%
          ggplot(aes(x=a, y=b)) +
          geom_point() +
          geom_text(data = . %>% distinct(p, rho, exp),
          aes(x = -Inf, y = Inf,label = paste("p=",p,"nrho=",rho)),
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~exp)


          enter image description here






          share|improve this answer























          • Very nice - I would not have thought of using distinct like that but it totally makes sense.

            – C. Murtaugh
            Nov 15 '18 at 16:41













          3












          3








          3







          Similar to the answer of camille, but you can do all in one run



          library(tidyverse)
          set.seed(123)
          df %>%
          group_by(exp) %>%
          mutate(p = cor.test(a, b)$p.value,
          rho = cor.test(a, b)$estimate) %>%
          mutate_at(vars(p, rho), signif, 2) %>%
          ggplot(aes(x=a, y=b)) +
          geom_point() +
          geom_text(data = . %>% distinct(p, rho, exp),
          aes(x = -Inf, y = Inf,label = paste("p=",p,"nrho=",rho)),
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~exp)


          enter image description here






          share|improve this answer













          Similar to the answer of camille, but you can do all in one run



          library(tidyverse)
          set.seed(123)
          df %>%
          group_by(exp) %>%
          mutate(p = cor.test(a, b)$p.value,
          rho = cor.test(a, b)$estimate) %>%
          mutate_at(vars(p, rho), signif, 2) %>%
          ggplot(aes(x=a, y=b)) +
          geom_point() +
          geom_text(data = . %>% distinct(p, rho, exp),
          aes(x = -Inf, y = Inf,label = paste("p=",p,"nrho=",rho)),
          hjust = -0.1, vjust = 1.1, lineheight = 1) +
          facet_wrap(~exp)


          enter image description here







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 15 '18 at 10:54









          JimbouJimbou

          9,85111230




          9,85111230












          • Very nice - I would not have thought of using distinct like that but it totally makes sense.

            – C. Murtaugh
            Nov 15 '18 at 16:41

















          • Very nice - I would not have thought of using distinct like that but it totally makes sense.

            – C. Murtaugh
            Nov 15 '18 at 16:41
















          Very nice - I would not have thought of using distinct like that but it totally makes sense.

          – C. Murtaugh
          Nov 15 '18 at 16:41





          Very nice - I would not have thought of using distinct like that but it totally makes sense.

          – C. Murtaugh
          Nov 15 '18 at 16:41

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53311214%2fadding-group-specific-text-data-to-faceted-plot-in-r-ggplot2%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Barbados

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3