2019-09-13

How to annotate a boxplot in ggplot2

Problem

We want to annotate a boxplot in ggplot2. In our example we will add Tukey's five number summary (minimum, lower-hinge, median, upper-hinge, and maximum).

fivenum(iris$Sepal.Width)
[1] 2.0 2.8 3.0 3.3 4.4
library(ggplot2)
ggplot(iris, aes(factor(0), Sepal.Width)) + 
geom_boxplot() + xlab("") + scale_x_discrete(breaks = NULL)

Solution

We store Tukey's five number summary as a data frame, and then pass it as the argument data inside geom_text to add text to the plot.

five <- data.frame(x = rep(1, 5), five = fivenum(iris$Sepal.Width))
ggplot(iris, aes(x = 0, y = Sepal.Width)) + 
  geom_boxplot() + xlab("") + scale_x_discrete(breaks = NULL) + 
  geom_text(data = five, aes(x = 0, y = five, label = five), nudge_x = 0.5)

References

2019-09-07

Return the sum of multiple columns with SUMPRODUCT

Problem

For a given lookup value we want to return the sum of multiple columns. In our table, for Year 1 we'd like to return the sum of January, February, April, and December.

Solution

  1. We use the function SUMPRODUCT with multiple AND (asterisk: *) and OR (plus: +) criteria.

  2. =SUMPRODUCT((B2:M4)*(A2:A4=B7)*
          ((B1:M1=B8)+(B1:M1=B9)+(B1:M1=B10)+(B1:M1=B11)))
    
    First we pass the range we want to sum (B2:M4), and then add the conditions: 1) Year 1 (A2:A4=B7); and 2) Months to sum: ((B1:M1=B8)+(B1:M1=B9)+(B1:M1=B10)+(B1:M1=B11))). In English, the year must be equal to Year 1 and the months must be January or February or April or December.

Related posts

Return the sum of multiple columns with VLOOKUP

Problem

For a given lookup value we want to return the sum of multiple columns. In our table, for Year 1 we'd like to return the sum of January, February, April, and December.

Solution

  1. With VLOOKUP we pass within the third argument col_index_num the array of columns we'd like to sum: {2,3,5,13}, always enclosed in curly brackets. This will return an array of 4 values {98,52,75,60}. :
  2. {=VLOOKUP(B7,A1:M4,{2,3,5,13},0)}
    
  3. To sum the elements of the array, we use the function sum and then press CTRL + SHIFT + ENTER or we can use the function SUMPRODUCT that doesn't require CTRL + SHIFT + ENTER.
  4. {=SUM(VLOOKUP(B7,A1:M4,{2,3,5,13},0))}
    =SUMPRODUCT(VLOOKUP(B7,A1:M4,{2,3,5,13},0))
    
  5. An different approach would be to use SUMPRODUCT with multiple OR criteria described in this post.

Related posts

2019-08-25

How to rename suffixes when joining tables in dplyr

Problem

When joining two tables with dplyr, the suffixes .x and .y will be added to the non-joined duplicate variables to disambiguate them. In our example, to the column mpg: mpg.x y mpg.y. How can override these suffixes?

library(dplyr) 
left_join(mtcars, mtcars[, c("mpg", 'cyl')], by = c("cyl")) %>% head()
  • Output
  •   mpg.x cyl disp  hp drat   wt  qsec vs am gear carb mpg.y
    1    21   6  160 110  3.9 2.62 16.46  0  1    4    4  21.0
    2    21   6  160 110  3.9 2.62 16.46  0  1    4    4  21.0
    3    21   6  160 110  3.9 2.62 16.46  0  1    4    4  21.4
    4    21   6  160 110  3.9 2.62 16.46  0  1    4    4  18.1
    5    21   6  160 110  3.9 2.62 16.46  0  1    4    4  19.2
    6    21   6  160 110  3.9 2.62 16.46  0  1    4    4  17.8
    

    Solution

    We can pass the argument suffix, a character vector of length 2 with the desired names. In our example, mpg_original (suffix _original) and mpg_new (suffix_new).

    left_join(mtcars, mtcars[,c("mpg","cyl")], 
                  by = c("cyl"), 
                  suffix = c("_original", "_new")) %>% head()
    
  • Output
  •   mpg_original cyl disp  hp drat   wt  qsec vs am gear carb mpg_new
    1           21   6  160 110  3.9 2.62 16.46  0  1    4    4    21.0
    2           21   6  160 110  3.9 2.62 16.46  0  1    4    4    21.0
    3           21   6  160 110  3.9 2.62 16.46  0  1    4    4    21.4
    4           21   6  160 110  3.9 2.62 16.46  0  1    4    4    18.1
    5           21   6  160 110  3.9 2.62 16.46  0  1    4    4    19.2
    6           21   6  160 110  3.9 2.62 16.46  0  1    4    4    17.8
    

    References

    2019-08-10

    Cómo representar una curva logarítmica en R

    Problema

    Queremos ajustar una curva logarítmica a un diagrama de dispersión.

    library(ggplot2)
    ggplot(mpg, aes(displ, hwy)) +
      geom_point()
    

    Solución

    Paquete base

    plot(hwy ~ displ, mpg)
    logEstimate <- lm(hwy ~ log(displ), data = mpg)
    curve(coef(logEstimate)[1] + coef(logEstimate)[2] * log(x), add = TRUE)
    
    ggplot2

    ggplot(mpg, aes(displ, hwy)) +
      geom_point() +
      stat_smooth(method = "lm", formula = y ~ log(x))
    

    Referencias

    How to plot a log curve in R

    Problem

    We want to fit a logarithmic curve to a scatterplot.

    library(ggplot2)
    ggplot(mpg, aes(displ, hwy)) +
      geom_point()
    

    Solution

    Base package

    plot(hwy ~ displ, mpg)
    logEstimate <- lm(hwy ~ log(displ), data = mpg)
    curve(coef(logEstimate)[1] + coef(logEstimate)[2] * log(x), add = TRUE)
    
    ggplot2

    ggplot(mpg, aes(displ, hwy)) +
      geom_point() +
      stat_smooth(method = "lm", formula = y ~ log(x))
    

    References

    2019-08-04

    How to do cross join in R?

    Problem

    We want to calculate a cross join, the Cartesian product of rows from tables —or elements of a vector— in the join. In other words, we want to combine each row from the first table with each row from the second table.

    Solution

    Two vectors

    • expand.grid
    • expand.grid(1:5, 1:5)
      
    • merge
    • merge(1:5, 1:5)
      
    • Cross join with sqldf
    • library(sqldf)
      df1 <- data.frame(a = 1:5)
      df2 <- df1
      sqldf("SELECT df1.a, df2.a FROM df1 
            CROSS JOIN df2")
      
    • Results
    •    x y
      1  1 1
      2  2 1
      3  3 1
      4  4 1
      5  5 1
      6  1 2
      7  2 2
      8  3 2
      9  4 2
      10 5 2
      11 1 3
      12 2 3
      13 3 3
      14 4 3
      15 5 3
      16 1 4
      17 2 4
      18 3 4
      19 4 4
      20 5 4
      21 1 5
      22 2 5
      23 3 5
      24 4 5
      25 5 5
      
    More than two vectors

    • expand.grid.
    • a <- c('europe', 'asia')
      b <- c('co2', 'temperature')
      c <- c('min', 'max')
      expand.grid(a, b, c)
      
          Var1        Var2 Var3
      1 europe         co2  min
      2   asia         co2  min
      3 europe temperature  min
      4   asia temperature  min
      5 europe         co2  max
      6   asia         co2  max
      7 europe temperature  max
      8   asia temperature  max
      

    References

    Nube de datos