• Load the readxl and tidyverse libraries.
library(readxl)
library(tidyverse)
  • Load FTIR_rocks.xlsx into a data.frame (in fact, tibble).
# Place the Rmd file you are working on in the same folder as the one containing the "Data" folder
# If you do so, the path is relative to where your working Rmd file is located :
df <- read_excel("Data/FTIR_rocks.xlsx")
# Otherwise, you need to provide the whole absolute path
# df <- read_excel("/Users/colin/Downloads/Data/FTIR_rocks.xlsx")
  • Rename the columns with simpler names, such as “w”, “r1”, “r2” and “r3”
names(df) <- c("w","r1","r2","r3")
  • Find the wavenumber value of the maximum of each spectrum
max1 <- df$w[which.max(df$r1)]
max2 <- df$w[which.max(df$r2)]
max3 <- df$w[which.max(df$r3)]
max1;max2;max3
## [1] 2924.912
## [1] 1594.092
## [1] 2925.876
  • Create a function norm01() that, given a vector, returns the vector normalized to [0,1]
norm01 <- function(x){
    (x-min(x))/(max(x)-min(x))
}
# check it's working
x <- 1:10
norm01(x)
##  [1] 0.0000000 0.1111111 0.2222222 0.3333333 0.4444444 0.5555556 0.6666667
##  [8] 0.7777778 0.8888889 1.0000000
  • Normalize all columns of FTIR intensity to [0,1]
# First, let's make the tibble tidy
df_tidy <- df %>% pivot_longer(cols=-w,
                    names_to="rock",
                    values_to="intensity")
df_tidy
## # A tibble: 14,154 × 3
##        w rock  intensity
##    <dbl> <chr>     <dbl>
##  1 5199. r1      0.00566
##  2 5199. r2      0.00225
##  3 5199. r3      0.0346 
##  4 5198. r1      0.00568
##  5 5198. r2      0.00191
##  6 5198. r3      0.0346 
##  7 5197. r1      0.00570
##  8 5197. r2      0.00186
##  9 5197. r3      0.0346 
## 10 5196. r1      0.00581
## # ℹ 14,144 more rows
# now add the new column 'intensity_n' containing the normalized intensities
df_tidy <- df_tidy %>% 
    group_by(rock) %>%
    mutate(intensity_n = norm01(intensity))
df_tidy
## # A tibble: 14,154 × 4
## # Groups:   rock [3]
##        w rock  intensity intensity_n
##    <dbl> <chr>     <dbl>       <dbl>
##  1 5199. r1      0.00566     0.00687
##  2 5199. r2      0.00225     0.00517
##  3 5199. r3      0.0346      0.0385 
##  4 5198. r1      0.00568     0.00689
##  5 5198. r2      0.00191     0.00437
##  6 5198. r3      0.0346      0.0385 
##  7 5197. r1      0.00570     0.00691
##  8 5197. r2      0.00186     0.00427
##  9 5197. r3      0.0346      0.0385 
## 10 5196. r1      0.00581     0.00705
## # ℹ 14,144 more rows
  • Using base graphics or ggplot2, as you wish, try to reproduce the following graphs:

P1 <- df_tidy %>%
    ggplot(aes(x=w, y=intensity_n, color=rock)) +
        # add the lines with thickness of 1
        geom_line(size=1) +
        # change the axis labels
        labs(x="Wavenumber [1/cm]", y="Intensity [arb. units]") +
        theme_bw() +
        # set the color to the wanted colors and give a name to 
        # the legend if you want to plot the legend
        # if this line is absent, ggplot uses its default colors (blue, red, green)
        scale_color_manual(values = c("black", "royalblue", "red"), name="Rock:") +
        # to remove the legend, set it to "none"
        # if you remove this line, the default is to show the legend on the right
        theme(legend.position = "top")
P2 <- df_tidy %>%
    ggplot(aes(x=w, 
               y=intensity_n + as.numeric(factor(rock)) - 1, 
               color=rock)) +
        geom_line(size=1)+
        labs(x="Wavenumber [1/cm]", y="Intensity [arb. units]")+
        theme_bw()+
        theme(legend.position = "none")+
        scale_color_manual(values = c("black", "royalblue", "red"))
library(patchwork)
P1+P2

LS0tCnRpdGxlIDogIlIgRXhlcmNpc2VzIC0gU3BlY3Ryb3Njb3BpYyBkYXRhIC0gU29sdXRpb24iCmRhdGUgIDogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6IAogICAgaHRtbF9kb2N1bWVudDoKICAgICAgICB0b2MgICAgICAgICAgICA6IHRydWUKICAgICAgICB0b2NfZmxvYXQgICAgICA6IHRydWUKICAgICAgICB0b2NfZGVwdGggICAgICA6IDQKICAgICAgICBoaWdobGlnaHQgICAgICA6IHRhbmdvCiAgICAgICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgICAgIGNvZGVfZG93bmxvYWQgIDogdHJ1ZQpwYXJhbXM6IAogICAgc29sdXRpb246CiAgICAgICAgdmFsdWU6IHRydWUKLS0tCgotIExvYWQgdGhlIGByZWFkeGxgIGFuZCBgdGlkeXZlcnNlYCBsaWJyYXJpZXMuCgpgYGB7ciBpbmNsdWRlPVRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9RkFMU0V9CmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgotIExvYWQgYEZUSVJfcm9ja3MueGxzeGAgaW50byBhIGBkYXRhLmZyYW1lYCAoaW4gZmFjdCwgYHRpYmJsZWApLgoKYGBge3IgaW5jbHVkZT1UUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPUZBTFNFfQojIFBsYWNlIHRoZSBSbWQgZmlsZSB5b3UgYXJlIHdvcmtpbmcgb24gaW4gdGhlIHNhbWUgZm9sZGVyIGFzIHRoZSBvbmUgY29udGFpbmluZyB0aGUgIkRhdGEiIGZvbGRlcgojIElmIHlvdSBkbyBzbywgdGhlIHBhdGggaXMgcmVsYXRpdmUgdG8gd2hlcmUgeW91ciB3b3JraW5nIFJtZCBmaWxlIGlzIGxvY2F0ZWQgOgpkZiA8LSByZWFkX2V4Y2VsKCJEYXRhL0ZUSVJfcm9ja3MueGxzeCIpCiMgT3RoZXJ3aXNlLCB5b3UgbmVlZCB0byBwcm92aWRlIHRoZSB3aG9sZSBhYnNvbHV0ZSBwYXRoCiMgZGYgPC0gcmVhZF9leGNlbCgiL1VzZXJzL2NvbGluL0Rvd25sb2Fkcy9EYXRhL0ZUSVJfcm9ja3MueGxzeCIpCmBgYAoKLSBSZW5hbWUgdGhlIGNvbHVtbnMgd2l0aCBzaW1wbGVyIG5hbWVzLCBzdWNoIGFzICJ3IiwgInIxIiwgInIyIiBhbmQgInIzIgoKYGBge3IgaW5jbHVkZT1UUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPUZBTFNFfQpuYW1lcyhkZikgPC0gYygidyIsInIxIiwicjIiLCJyMyIpCmBgYAoKLSBGaW5kIHRoZSB3YXZlbnVtYmVyIHZhbHVlIG9mIHRoZSBtYXhpbXVtIG9mIGVhY2ggc3BlY3RydW0KCmBgYHtyIGluY2x1ZGU9VFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlPUZBTFNFLCBjYWNoZT1GQUxTRX0KbWF4MSA8LSBkZiR3W3doaWNoLm1heChkZiRyMSldCm1heDIgPC0gZGYkd1t3aGljaC5tYXgoZGYkcjIpXQptYXgzIDwtIGRmJHdbd2hpY2gubWF4KGRmJHIzKV0KbWF4MTttYXgyO21heDMKYGBgCgotIENyZWF0ZSBhIGZ1bmN0aW9uIGBub3JtMDEoKWAgdGhhdCwgZ2l2ZW4gYSB2ZWN0b3IsIHJldHVybnMgdGhlIHZlY3RvciBub3JtYWxpemVkIHRvIFswLDFdCgpgYGB7ciBpbmNsdWRlPVRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9RkFMU0V9Cm5vcm0wMSA8LSBmdW5jdGlvbih4KXsKICAgICh4LW1pbih4KSkvKG1heCh4KS1taW4oeCkpCn0KIyBjaGVjayBpdCdzIHdvcmtpbmcKeCA8LSAxOjEwCm5vcm0wMSh4KQpgYGAKCi0gTm9ybWFsaXplIGFsbCBjb2x1bW5zIG9mIEZUSVIgaW50ZW5zaXR5IHRvIFswLDFdCgpgYGB7ciBpbmNsdWRlPVRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9RkFMU0V9CiMgRmlyc3QsIGxldCdzIG1ha2UgdGhlIHRpYmJsZSB0aWR5CmRmX3RpZHkgPC0gZGYgJT4lIHBpdm90X2xvbmdlcihjb2xzPS13LAogICAgICAgICAgICAgICAgICAgIG5hbWVzX3RvPSJyb2NrIiwKICAgICAgICAgICAgICAgICAgICB2YWx1ZXNfdG89ImludGVuc2l0eSIpCmRmX3RpZHkKIyBub3cgYWRkIHRoZSBuZXcgY29sdW1uICdpbnRlbnNpdHlfbicgY29udGFpbmluZyB0aGUgbm9ybWFsaXplZCBpbnRlbnNpdGllcwpkZl90aWR5IDwtIGRmX3RpZHkgJT4lIAogICAgZ3JvdXBfYnkocm9jaykgJT4lCiAgICBtdXRhdGUoaW50ZW5zaXR5X24gPSBub3JtMDEoaW50ZW5zaXR5KSkKZGZfdGlkeQpgYGAKCi0gVXNpbmcgYmFzZSBncmFwaGljcyBvciBgZ2dwbG90MmAsIGFzIHlvdSB3aXNoLCB0cnkgdG8gcmVwcm9kdWNlIHRoZSBmb2xsb3dpbmcgZ3JhcGhzOgoKYGBge3IgcGxvdHMsIGVjaG89RkFMU0UsIGZpZy5jYXA9IiIsIGZpZy5hbGlnbj0iY2VudGVyIiwgb3V0LndpZHRoPSI1MCUifQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiRGF0YS9wbG90MS5wbmciKQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiRGF0YS9wbG90Mi5wbmciKQpgYGAKCmBgYHtyIGluY2x1ZGU9VFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlPUZBTFNFLCBjYWNoZT1GQUxTRX0KUDEgPC0gZGZfdGlkeSAlPiUKICAgIGdncGxvdChhZXMoeD13LCB5PWludGVuc2l0eV9uLCBjb2xvcj1yb2NrKSkgKwogICAgICAgICMgYWRkIHRoZSBsaW5lcyB3aXRoIHRoaWNrbmVzcyBvZiAxCiAgICAgICAgZ2VvbV9saW5lKHNpemU9MSkgKwogICAgICAgICMgY2hhbmdlIHRoZSBheGlzIGxhYmVscwogICAgICAgIGxhYnMoeD0iV2F2ZW51bWJlciBbMS9jbV0iLCB5PSJJbnRlbnNpdHkgW2FyYi4gdW5pdHNdIikgKwogICAgICAgIHRoZW1lX2J3KCkgKwogICAgICAgICMgc2V0IHRoZSBjb2xvciB0byB0aGUgd2FudGVkIGNvbG9ycyBhbmQgZ2l2ZSBhIG5hbWUgdG8gCiAgICAgICAgIyB0aGUgbGVnZW5kIGlmIHlvdSB3YW50IHRvIHBsb3QgdGhlIGxlZ2VuZAogICAgICAgICMgaWYgdGhpcyBsaW5lIGlzIGFic2VudCwgZ2dwbG90IHVzZXMgaXRzIGRlZmF1bHQgY29sb3JzIChibHVlLCByZWQsIGdyZWVuKQogICAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJibGFjayIsICJyb3lhbGJsdWUiLCAicmVkIiksIG5hbWU9IlJvY2s6IikgKwogICAgICAgICMgdG8gcmVtb3ZlIHRoZSBsZWdlbmQsIHNldCBpdCB0byAibm9uZSIKICAgICAgICAjIGlmIHlvdSByZW1vdmUgdGhpcyBsaW5lLCB0aGUgZGVmYXVsdCBpcyB0byBzaG93IHRoZSBsZWdlbmQgb24gdGhlIHJpZ2h0CiAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpClAyIDwtIGRmX3RpZHkgJT4lCiAgICBnZ3Bsb3QoYWVzKHg9dywgCiAgICAgICAgICAgICAgIHk9aW50ZW5zaXR5X24gKyBhcy5udW1lcmljKGZhY3Rvcihyb2NrKSkgLSAxLCAKICAgICAgICAgICAgICAgY29sb3I9cm9jaykpICsKICAgICAgICBnZW9tX2xpbmUoc2l6ZT0xKSsKICAgICAgICBsYWJzKHg9IldhdmVudW1iZXIgWzEvY21dIiwgeT0iSW50ZW5zaXR5IFthcmIuIHVuaXRzXSIpKwogICAgICAgIHRoZW1lX2J3KCkrCiAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiYmxhY2siLCAicm95YWxibHVlIiwgInJlZCIpKQpsaWJyYXJ5KHBhdGNod29yaykKUDErUDIKYGBgCgo=