The script reads many csv files in one dataframe, assigns the file names as a variable, and offers two versions for plotting. Example files can be found here (in the HPLC folder): https://www.dropbox.com/sh/zzf7y3ijwkat55e/AABUvp7BAARIdYBqZWgk1E37a?dl=0
Put the csv files in your working dir and execute the script
# Angelov 2017
# Script to process HPLC chromatogram data from Chromeleon csv files
# The script reads many csv files in one dataframe, assigns the file names as a variable, and offers two versions for plotting
# HPLC - Dionex
# Chromeleon 7.2.3.0, locale - German, therefore the decimal mark problem.
#
# example files can be found here (in the HPLC folder):
# https://www.dropbox.com/sh/zzf7y3ijwkat55e/AABUvp7BAARIdYBqZWgk1E37a?dl=0
# put the files in your working dir and execute the script (press Source button on top)
# load packages and define read function
library(purrr)
library(tidyverse)
library(plotly)
library(manipulate)
#this function reads the files and adds a variable with the file name
read_chrom <- function(x) {
read_delim(x, "\t", col_names = FALSE, skip = 43, locale = locale(decimal_mark = ",")) %>%
select(-X2) %>%
mutate(filename = x) # here some work needed to simplify naming
}
# read files
files <- list.files(pattern = ".txt")
df <- map(files, read_chrom) %>%
map_df(bind_rows) %>%
rename(time=X1, sig = X3)
# use samples.tab file to assign sample names, file has two tab-sep, named columns (filename and sample)
# then join with df
# prepare sample template file
write_delim(
tibble(filenames = files, sample = NA),
"samples-template.tab",
delim = "\t")
# now fill-in the sample names and save the file as "samples.tab"
readline(prompt = "Fill-in sample names in \"samples-template.tab\", save as \"samples.tab\" and hit [enter] to continue")
[1] ""
sampledf <- read_delim("samples.tab", delim = "\t", trim_ws = TRUE)
df2 <- left_join(df, sampledf, by = "filename")
# a shifted plot in plotly, to estimate axis scaling
# if you get an error, install the devel version of ggplot and update plotly
# I introduce a shift using the sample names as factors
# plotly
offset <- 20 # play with y-offset
#df2$sample <- as.factor(df2$sample) # convert to factor to use in the next step
p <- df2 %>% mutate(yshifted = as.numeric(as.factor(sample)) * offset + sig) %>% # use the factor level to introduce shift.
# xshifted = as.numeric(sample) + time) %>% # could be used for x-axis shift also.
plot_ly(x = ~time) %>%
add_lines(y = ~ yshifted, color = ~sample, colors = "Paired")
p
# a ggplot version for saving, using manual adjusting axis scales
df2 %>% mutate(yshifted = as.numeric(as.factor(sample)) * offset + sig) %>%
ggplot(aes(x = time, y = yshifted)) +
geom_line(aes(color=sample)) +
scale_x_continuous(limits = c(5,40)) +
scale_y_continuous(limits = c(0,500)) +
theme_bw()

# todo: add sliders for the y and x offsets
#cleanup
rm(df)
rm(files)
#
#
# play around with the manipulate package,
# this works:)
manipulate(
{df2 %>% filter(grepl(substrate, sample)) %>%
ggplot(aes(x = time, y = shift * as.numeric(as.factor(sample)) + sig)) +
geom_line(aes(color=sample)) +
scale_x_continuous(limits = c(xmin, xmax)) +
scale_y_continuous(limits = c(0,ymax)) +
theme_bw()}, #here ends the plotting func and come the manipulate arguments
shift = slider(0,200, step=10),
xmin = slider(0,20, step=1, initial = 0),
xmax = slider(30,70, step = 2, initial = 70),
ymax = slider(100, 1000, step = 10, initial = 1000),
substrate = picker("PGA" = "PGA|mix", "Pectin" = "Pectin|mix", "all" = "*", initial = "all"))

#
#
readline(prompt = "Check out both the Plots and Viewer tabs, hit [enter] to end script. \nCheers!")
[1] ""
#end of script
LS0tCnRpdGxlOiAiU2NyaXB0IHRvIHByb2Nlc3MgSFBMQyBjaHJvbWF0b2dyYW0gZGF0YSBmcm9tIENocm9tZWxlb24gY3N2IGZpbGVzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGUgc2NyaXB0IHJlYWRzIG1hbnkgY3N2IGZpbGVzIGluIG9uZSBkYXRhZnJhbWUsIGFzc2lnbnMgdGhlIGZpbGUgbmFtZXMgYXMgYSB2YXJpYWJsZSwgYW5kIG9mZmVycyB0d28gdmVyc2lvbnMgZm9yIHBsb3R0aW5nLiAKRXhhbXBsZSBmaWxlcyBjYW4gYmUgZm91bmQgaGVyZSAoaW4gdGhlIEhQTEMgZm9sZGVyKToKaHR0cHM6Ly93d3cuZHJvcGJveC5jb20vc2gvenpmN3kzaWp3a2F0NTVlL0FBQlV2cDdCQUFSSWRZQnFaV2drMUUzN2E/ZGw9MAoKUHV0IHRoZSBjc3YgZmlsZXMgaW4geW91ciB3b3JraW5nIGRpciBhbmQgZXhlY3V0ZSB0aGUgc2NyaXB0CgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBBbmdlbG92IDIwMTcKIyBTY3JpcHQgdG8gcHJvY2VzcyBIUExDIGNocm9tYXRvZ3JhbSBkYXRhIGZyb20gQ2hyb21lbGVvbiBjc3YgZmlsZXMKIyBUaGUgc2NyaXB0IHJlYWRzIG1hbnkgY3N2IGZpbGVzIGluIG9uZSBkYXRhZnJhbWUsIGFzc2lnbnMgdGhlIGZpbGUgbmFtZXMgYXMgYSB2YXJpYWJsZSwgYW5kIG9mZmVycyB0d28gdmVyc2lvbnMgZm9yIHBsb3R0aW5nCiMgSFBMQyAtIERpb25leAojIENocm9tZWxlb24gNy4yLjMuMCwgbG9jYWxlIC0gR2VybWFuLCB0aGVyZWZvcmUgdGhlIGRlY2ltYWwgbWFyayBwcm9ibGVtLgojIAojIGV4YW1wbGUgZmlsZXMgY2FuIGJlIGZvdW5kIGhlcmUgKGluIHRoZSBIUExDIGZvbGRlcik6CiMgaHR0cHM6Ly93d3cuZHJvcGJveC5jb20vc2gvenpmN3kzaWp3a2F0NTVlL0FBQlV2cDdCQUFSSWRZQnFaV2drMUUzN2E/ZGw9MAojIHB1dCB0aGUgZmlsZXMgaW4geW91ciB3b3JraW5nIGRpciBhbmQgZXhlY3V0ZSB0aGUgc2NyaXB0IChwcmVzcyBTb3VyY2UgYnV0dG9uIG9uIHRvcCkKIyBsb2FkIHBhY2thZ2VzIGFuZCBkZWZpbmUgcmVhZCBmdW5jdGlvbgpsaWJyYXJ5KHB1cnJyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkobWFuaXB1bGF0ZSkKI3RoaXMgZnVuY3Rpb24gcmVhZHMgdGhlIGZpbGVzIGFuZCBhZGRzIGEgdmFyaWFibGUgd2l0aCB0aGUgZmlsZSBuYW1lCnJlYWRfY2hyb20gPC0gZnVuY3Rpb24oeCkgewogIHJlYWRfZGVsaW0oeCwgIlx0IiwgY29sX25hbWVzID0gRkFMU0UsIHNraXAgPSA0MywgbG9jYWxlID0gbG9jYWxlKGRlY2ltYWxfbWFyayA9ICIsIikpICU+JSAKICAgIHNlbGVjdCgtWDIpICU+JQogICAgbXV0YXRlKGZpbGVuYW1lID0geCkgIyBoZXJlIHNvbWUgd29yayBuZWVkZWQgdG8gc2ltcGxpZnkgbmFtaW5nCiAgICB9CgojIHJlYWQgZmlsZXMKZmlsZXMgPC0gbGlzdC5maWxlcyhwYXR0ZXJuID0gIi50eHQiKSAjIG9yIHdoYXRldmVyIHRoZSBleHRlbnNpb24KZGYgPC0gbWFwKGZpbGVzLCByZWFkX2Nocm9tKSAlPiUgIAogICAgICAgICAgbWFwX2RmKGJpbmRfcm93cykgJT4lIAogICAgICAgICAgcmVuYW1lKHRpbWU9WDEsIHNpZyA9IFgzKQojIHVzZSBzYW1wbGVzLnRhYiBmaWxlIHRvIGFzc2lnbiBzYW1wbGUgbmFtZXMsIGZpbGUgaGFzIHR3byB0YWItc2VwYXJhdGVkLCBuYW1lZCBjb2x1bW5zIChmaWxlbmFtZSBhbmQgc2FtcGxlKQojIHRoZW4gam9pbiB3aXRoIGRmCiMgcHJlcGFyZSBzYW1wbGUgdGVtcGxhdGUgZmlsZQp3cml0ZV9kZWxpbSgKICB0aWJibGUoZmlsZW5hbWVzID0gZmlsZXMsIHNhbXBsZSA9IE5BKSwKICAic2FtcGxlcy10ZW1wbGF0ZS50YWIiLAogIGRlbGltID0gIlx0IikgCiMgbm93IGZpbGwtaW4gdGhlIHNhbXBsZSBuYW1lcyBhbmQgc2F2ZSB0aGUgZmlsZSBhcyAic2FtcGxlcy50YWIiCnJlYWRsaW5lKHByb21wdCA9ICJGaWxsLWluIHNhbXBsZSBuYW1lcyBpbiBcInNhbXBsZXMtdGVtcGxhdGUudGFiXCIsIHNhdmUgYXMgXCJzYW1wbGVzLnRhYlwiIGFuZCBoaXQgW2VudGVyXSB0byBjb250aW51ZSIpCgpzYW1wbGVkZiA8LSByZWFkX2RlbGltKCJzYW1wbGVzLnRhYiIsIGRlbGltID0gIlx0IiwgdHJpbV93cyA9IFRSVUUpCmRmMiA8LSBsZWZ0X2pvaW4oZGYsIHNhbXBsZWRmLCBieSA9ICJmaWxlbmFtZSIpCgojIGEgc2hpZnRlZCBwbG90IGluIHBsb3RseSwgdG8gZXN0aW1hdGUgYXhpcyBzY2FsaW5nCiMgaWYgeW91IGdldCBhbiBlcnJvciwgaW5zdGFsbCB0aGUgZGV2ZWwgdmVyc2lvbiBvZiBnZ3Bsb3QgYW5kIHVwZGF0ZSBwbG90bHkKIyBJIGludHJvZHVjZSBhIHNoaWZ0IHVzaW5nIHRoZSBzYW1wbGUgbmFtZXMgYXMgZmFjdG9ycwoKIyBwbG90bHkKb2Zmc2V0IDwtIDIwICMgcGxheSB3aXRoIHktb2Zmc2V0CiNkZjIkc2FtcGxlIDwtIGFzLmZhY3RvcihkZjIkc2FtcGxlKSAgIyBjb252ZXJ0IHRvIGZhY3RvciB0byB1c2UgaW4gdGhlIG5leHQgc3RlcApwIDwtIGRmMiAlPiUgbXV0YXRlKHlzaGlmdGVkID0gYXMubnVtZXJpYyhhcy5mYWN0b3Ioc2FtcGxlKSkgKiBvZmZzZXQgKyBzaWcpICU+JSAjIHVzZSB0aGUgZmFjdG9yIGxldmVsIHRvIGludHJvZHVjZSBzaGlmdC4KIyAgICAgICAgICAgICAgICAgICAgeHNoaWZ0ZWQgPSBhcy5udW1lcmljKHNhbXBsZSkgKyB0aW1lKSAlPiUgICAgICAgICAgICAgICAgICAgIyBjb3VsZCBiZSB1c2VkIGZvciB4LWF4aXMgc2hpZnQgYWxzby4KICBwbG90X2x5KHggPSB+dGltZSkgJT4lIAogIGFkZF9saW5lcyh5ID0gfiB5c2hpZnRlZCwgY29sb3IgPSAgfnNhbXBsZSwgY29sb3JzID0gIlBhaXJlZCIpCnAKCiMgYSBnZ3Bsb3QgdmVyc2lvbiBmb3Igc2F2aW5nLCB1c2luZyBtYW51YWwgYWRqdXN0aW5nIGF4aXMgc2NhbGVzCiAgZGYyICU+JSBtdXRhdGUoeXNoaWZ0ZWQgPSBhcy5udW1lcmljKGFzLmZhY3RvcihzYW1wbGUpKSAqIG9mZnNldCArIHNpZykgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdGltZSwgeSA9IHlzaGlmdGVkKSkgKyAKICBnZW9tX2xpbmUoYWVzKGNvbG9yPXNhbXBsZSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYyg1LDQwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsNTAwKSkgKwogIHRoZW1lX2J3KCkKIyB0b2RvOiBhZGQgc2xpZGVycyBmb3IgdGhlIHkgYW5kIHggb2Zmc2V0cwojY2xlYW51cApybShkZikKcm0oZmlsZXMpCiMKIwojIHBsYXkgYXJvdW5kIHdpdGggdGhlIG1hbmlwdWxhdGUgcGFja2FnZSwgCiMgdGhpcyB3b3JrczopCm1hbmlwdWxhdGUoCiAgICAgIHtkZjIgJT4lIGZpbHRlcihncmVwbChzdWJzdHJhdGUsIHNhbXBsZSkpICU+JSAKICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeCA9IHRpbWUsIHkgPSBzaGlmdCAqIGFzLm51bWVyaWMoYXMuZmFjdG9yKHNhbXBsZSkpICsgc2lnKSkgKwogICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyhjb2xvcj1zYW1wbGUpKSArCiAgICAgICAgICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYyh4bWluLCB4bWF4KSkgKwogICAgICAgICAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCx5bWF4KSkgKwogICAgICAgICAgICAgICAgdGhlbWVfYncoKX0sICNoZXJlIGVuZHMgdGhlIHBsb3R0aW5nIGZ1bmMgYW5kIGNvbWUgdGhlIG1hbmlwdWxhdGUgYXJndW1lbnRzCiAgICBzaGlmdCA9IHNsaWRlcigwLDIwMCwgc3RlcD0xMCksCiAgICB4bWluID0gc2xpZGVyKDAsMjAsIHN0ZXA9MSwgaW5pdGlhbCA9IDApLAogICAgeG1heCA9IHNsaWRlcigzMCw3MCwgc3RlcCA9IDIsIGluaXRpYWwgPSA3MCksCiAgICB5bWF4ID0gc2xpZGVyKDEwMCwgMTAwMCwgc3RlcCA9IDEwLCBpbml0aWFsID0gMTAwMCksCiAgICBzdWJzdHJhdGUgPSBwaWNrZXIoIlBHQSIgPSAiUEdBfG1peCIsICJQZWN0aW4iID0gIlBlY3RpbnxtaXgiLCAiYWxsIiA9ICIqIiwgaW5pdGlhbCA9ICJhbGwiKSkKIwojCnJlYWRsaW5lKHByb21wdCA9ICJDaGVjayBvdXQgYm90aCB0aGUgUGxvdHMgYW5kIFZpZXdlciB0YWJzLCBoaXQgW2VudGVyXSB0byBlbmQgc2NyaXB0LiBcbkNoZWVycyEiKQojZW5kIG9mIHNjcmlwdApgYGAKCgo=