Using R: simple Gantt chart with ggplot2

Jeremy Yoder’s code for a simple Gantt chart on the Molecular Ecologist blog uses geom_line and gather to prepare the data structure. I like using geom_linerange and a coord_flip, which lets you use start and end columns directly without pivoting.

Here is a very serious data frame of activities:

# A tibble: 6 x 4
  activity       category        start               end                
                                                  
1 Clean house    preparations    2020-07-01 00:00:00 2020-07-03 00:00:00
2 Pack bags      preparations    2020-07-05 10:00:00 2020-07-05 17:00:00
3 Run to train   travel          2020-07-05 17:00:00 2020-07-05 17:15:00
4 Sleep on train travel          2020-07-05 17:15:00 2020-07-06 08:00:00
5 Procrastinate  procrastination 2020-07-01 00:00:00 2020-07-05 00:00:00
6 Sleep          vacation        2020-07-06 08:00:00 2020-07-09 00:00:00

And here is the code:


library(ggplot2)
library(readr)

activities <- read_csv("activities.csv")

## Set factor level to order the activities on the plot
activities$activity <- factor(activities$activity,
                              levels = activities$activity[nrow(activities):1])
    
plot_gantt <- qplot(ymin = start,
                    ymax = end,
                    x = activity,
                    colour = category,
                    geom = "linerange",
                    data = activities,
                    size = I(5)) +
    scale_colour_manual(values = c("black", "grey", "purple", "yellow")) +
    coord_flip() +
    theme_bw() +
    theme(panel.grid = element_blank()) +
    xlab("") +
    ylab("") +
    ggtitle("Vacation planning")

Using R: 10 years with R

Yesterday, 29 Feburary 2020, was the 20th anniversary of the release R 1.0.0. Jozef Hajnala’s blog has a cute anniversary post with some trivia. I realised that it is also (not to the day, but to the year) my R anniversary.

I started using R in 2010, during my MSc project in Linköping. Daniel Nätt, who was a PhD student there at the time, was using it for gene expression and DNA methylation work. I think that was the reason he was pulled into R; he needed the Bioconductor packages for microarrays. He introduced me. Thanks, Daniel!

I think I must first have used it to do something with qPCR melting curves. I remember that I wrote some function to reshape/pivot data between long and wide format. It was probably an atrocity of nested loops and hard bracket indexing. Coming right from an undergraduate programme with courses using Ada and C++, even if we had also used Minitab for statistics and Matlab for engineering, I spoke R with a strong accent. At any rate, I was primed to think that doing my data analysis with code was a good idea, and jumped at the opportunity to learn a tool for it. Thanks, undergraduate programme!

I think the easiest thing to love about R is the package system. You can certainly end up in dependency hell with R and metaphorically shoot your own foot, especially on a shared high performance computing system. But I wouldn’t run into any of that until after several years. I was, and still am, impressed by how packages just worked, and could do almost anything. So, the Bioconductor packages were probably, indirectly, why I was introduced to R, and after that, my R story can be told in a series of packages. Thanks, CRAN!

The next package was R/qtl, that I relied on for my PhD. I had my own copy of the R/qtl book. For a period, I probably wrote thing every day:

library(qtl)

cross <- read.cross(file = "F8_geno_trim.csv", format = "csv")

R/qtl is one of my favourite pieces or research software, relatively friendly and with lots of documentation. Thanks, R/qtl developers!

Of course it was Dom Wright, who was my PhD supervisor, who introduced me to R/qtl, and I think it was also he who introduced me to ggplot2. At least he used it, and at some point we were together trying to fix the formatting of a graph, probably with some ugly hack. I decided to use ggplot2 as much as possible, and as it is wont to, ggplot2 made me care about rearranging data, thus leading to reshape2 and plyr. ”The magic is not in plotting the data but in tidying and rearranging the data for plotting.” After a while, most everything I wrote used the ddply function in some way. Thank you, Hadley Wickham!

Then came the contemporary tidyverse. For the longest time, I was uneasy with tidyr, and I’m still not a regular purrr user, but one can’t avoid loving dplyr. How much? My talk at the Swedish Bioinformatics Workshop in 2016 had a slide expressing my love of the filter function. It did not receive the cheers that the function deserves. Maybe the audience were Python users. With new file reading functions, new data frames and functions to manipulate data frames, modern R has become smoother and friendlier. Thanks, tidyverse developers!

The history of R on this blog started in 2011, originally as a way to make notes for myself or, ”a fellow user who’s trying to google his or her way to a solution”. This turned into a series of things to help teach R to biologists around me.

There was the Slightly different introduction to R series of blog posts. It used packages that feel somewhat outdated, and today, I don’t think there’s anything even slightly different about advocating RStudio, and teaching ggplot2 from the beginning.

This spawned a couple of seminars in course for PhD students, which were updated for the Wright lab computation lunches, and eventually turned into a course of its own given in 2017. It would be fun to update it and give it again.

The last few years, I’ve been using R for reasonably large genome datasets in a HPC environment, and gotten back to the beginnings, I guess, by using Bioconducor a lot more. However, the package that I think epitomises the last years of my R use is AlphaSimR, developed by colleagues in Edinburgh. It’s great to be able throw together a quick simulation to check how some feature of genetics behaves. AlphaSimR itself is also an example of how far the R/C++ integration has come with RCpp and RCppArmadillo. Thanks, Chris!

In summary, R is my tool of choice for almost anything. I hope we’ll still be using it, in new and interesting ways, in another ten years. Thank you, R core team!

Reflektioner om högskolepedagogik, tagning 2

Kära dagbok,

Mer tankar från fortsättningskurs i högskolepedagogik.

På det andra kurstillfället ägnade vi rätt mycket tid åt ett romantiskt ideal för universitetet: både passet om pedagogisk utveckling i ett större sammanhang och passet om forskningsanknuten undervisning drog mycket inspiration från Humboldts ideal om högre utbildning som en helhet utbildning och forskning, som ska bibringa studenterna bildning och en generell färdighet att tänka självständigt, snarare än ämnes- och yrkeskunskaper.

Det står i högskolelagen och allt:

Verksamheten skall bedrivas så att det finns ett nära samband mellan forskning och utbildning.

Utbildning på grundnivå ska utveckla studenternas
– förmåga att göra självständiga och kritiska bedömningar,
– förmåga att självständigt urskilja, formulera och lösa problem, och
– beredskap att möta förändringar i arbetslivet.

Inom det område som utbildningen avser ska studenterna, utöver kunskaper och färdigheter, utveckla förmåga att
– söka och värdera kunskap på vetenskaplig nivå,
– följa kunskapsutvecklingen, och
– utbyta kunskaper även med personer utan specialkunskaper inom området.

Men lagen skriver också om arbetslivet, yrkesverksamhet och så vidare. Det låter som en blandning av den ovanstående visionen och andra hänsyn, och det överensstämmer kanske med universitetets historia som innehåller både holistisk Humboldt och en start som glorifierat prästseminarium.

Sådant pratade vi alltså om. Vad är ett universitet egentligen? Vad är poängen med den typ av utbildning som vi driver? Jag fick några gånger intrycket att den här delen av kursen handlade om att övertyga oss om att bildningsideal är bra och viktigt.

Men den lokala miljön är förmodligen ännu viktigare än den större inramningen. En bra miljö med kollegor som bryr sig och stöttar varandra hjälper förstås att göra undervisningen bättre. Mårtensson & Roxå (2011) tittade på fyra ”starka akademiska mikrokulturer”, det vill säga ställen på universitet där undervisning och forskning ansågs fungera väldigt bra. Som man kanske kan vänta sig är det här grupper där man håller undervisning för väldigt viktigt, har förtroende för varandra, har goda relationer med andra, och upplever ett gemensamt ärende.

Ärenden ifråga verkade vara långsiktiga mål som var riktade utåt. Poängen var att forma fältet, utbilda studenter som kommer att utveckla yrket, påverka omvärlden. Inte ”att bli en excellent utbildningsmiljö”, eller något sådant som förmodligen står i dokument på högre nivå i organisationen. Författarna använder ordet ”enterprise”. Det påminner om skillnaden mellan extern och intern motivation hos den som lär sig. Klart läraren också blir mer driven av av intern motivation som en önskan att förändra sitt fält, än av extern motivation som att universitetet har en strategi att bli bäst på undervisning.

Det kom också fram att i de här miljöerna såg man undervisning inte bara som väldigt viktigt, utan som något som är oskiljaktigt från forskning. På så sätt ligger de också i linje med Humboldt.

Sätten att göra forskningsanknuten undervisning kan (såklart, som allting annat här i världen, beskrivas med en fyrfälting):

Det vill säga, undervisningen kan vara inriktad på forskningsresultat eller på forskningsprocesser, och det kan vara läraren som berättar eller studenten som gör. Forskningsanknytning kan alltså bestå i uppdatera materialet med det senaste från forskningsfronten (eller i alla fall något senare än det som står i läroboken), avslöja insider-information om hur forskningen går till, låta studenter själva läsa och analysera primär forskningslitteratur, eller låta studenter öva forskningsmetoder. Jag gillade särskilt en formulering som Göran Hartman använde om uppgifter där det inte finns en färdig lösning ”som ni lärare sitter och tjuvhåller på”.

Har jag jobbat något med forskningsanknytning? Ja, mest i det lärarledda innehållsinriktade hörnet. Det är ju bland det roliga med att göra en ny föreläsning, att försöka hitta någon forskningsartikel att passa in. Förstå min glädje när jag såg ett Tinbergen-citat mitt i en tung Drosophila-genetikstudie (Hoopfer et al 2015) och hittade en ursäkt att ta med den i en gästföreläsning om beteendegenetik. Det var ett litet exempel, men ändå.

Jag lärde mig också ett nytt fint ord. Jag hade ingen aning om att det rätt prosaiska svenska ”forskningsanknuten undervisning” på engelska heter ”the research–teaching nexus”. Fint ska det vara.

Using R: from plyr to purrr, part 0 out of however many

This post is me thinking out loud about applying functions to vectors or lists and getting data frames back.

Using R is an ongoing process of finding nice ways to throw data frames, lists and model objects around. While tidyr has arrived at a comfortable way to reshape dataframes with pivot_longer and pivot_wider, I don’t always find the replacements for the good old plyr package as satisfying.

Here is an example of something I used to like to do with plyr. Don’t laugh!

Assume we have a number of text files, all in the same format, that we need to read and combine. This arises naturally if you run some kind of analysis where the dataset gets split into chunks, like in genetics, where chunks might be chromosomes.

## Generate vector of file names
files <- paste("data/chromosome", 1:20, ".txt", sep = "")

library(plyr)
library(readr)
genome <- ldply(files, read_tsv)

This gives us one big data frame, containing the rows from all those files.

If we want to move on from plyr, what are our options?

We can go old school with base R functions lapply and Reduce.

library(readr)

chromosomes <- lapply(files, read_tsv)
genome <- Reduce(rbind, chromosomes)

Here, we first let lapply read each file and store it in a list. Then we let Reduce fold the list with rbind, which binds the data frames in the list together, one below the other.

If that didn’t make sense, here it is again: lapply maps a function to each element of a vector or list, collecting the results in a list. Reduce folds the elements in a list together, using a function that takes in two arguments. The first argument will be the results it’s accumulated so far, and the second argument will be the next element of the list.

In the end, this leaves us, as with ldply, with one big data frame.

We can also use purrr‘s map_dfr. This seems to be the contemporary most elegant solution:

library(purrr)
library(readr)

genome <- map_dfr(files, read_tsv)

map_dfr, like good old ldply will map over a vector or list, and collect resulting data frames. The ”r” in the name means adding the next data frame as rows. There is also a ”c” version (map_dfc) for adding as columns.

Things that really don’t matter: megabase or megabasepair

Should we talk about physical distance in genetics as number of base pairs (kbp, Mbp, and so on) or bases (kb, Mb)?

I got into a discussion about this recently, and I said I’d continue the struggle on my blog. Here it is. Let me first say that I don’t think this matters at all, and if you make a big deal out of this (or whether ”data” can be singular, or any of those inconsequential matters of taste we argue about for amusement), you shouldn’t. See this blog post as an exorcism, helping me not to trouble my colleagues with my issues.

What I’m objecting to is mostly the inconsistency of talking about long stretches of nucleotides as ”kilobase” and ”megabase” but talking about short stretches as ”base pairs”. I don’t think it’s very common to call a 100 nucleotide stretch ”a 100 b sequence”; I would expect ”100 bp”. For example, if we look at Ensembl, they might describe a large region as 1 Mb, but if you zoom in a lot, they give length in bp. My impression is that this is a common practice. However, if you consistently use ”bases” and ”megabase”, more power to you.

Unless you’re writing a very specific kind of bioinformatics paper, the risk of confusion with the computer storage unit isn’t a problem. But there are some biological arguments.

A biological argument for ”base”, might be that we care about the identity of the base, not the base pairing. We note only one nucleotide down when we write a nucleic acid sequence. The base pair is a different thing: that base bound to the one on the other strand that it’s paired with, or, if the DNA or RNA is single-stranded, it’s not even paired at all.

Conversely, a biochemical argument for ”base pair” might be that in a double-stranded molecule, the base pair is the relevant informational unit. We may only write one base in our nucleotide sequence for convenience, but because of the rules of base pairing, we know the complementing pair. In this case, maybe we should use ”base” for single-stranded molecules.

If we consult two more or less trustworthy sources, The Encylopedia of Life Sciences and Wiktionary, they both seem to take this view.

eLS says:

A megabase pair, abbreviated Mbp, is a unit of length of nucleic acids, equal to one million base pairs. The term ‘megabase’ (or Mb) is commonly used inter-changeably, although strictly this would refer to a single-stranded nucleic acid.

Wiktionary says:

A length of nucleic acid containing one million nucleotides (bases if single-stranded, base pairs if double-stranded)

Please return next week for the correct pronunciation of ”loci”.

Literature

Dear, P.H. (2006). Megabase Pair (Mbp). eLS.

Reflektion om högskolepedagogik, apropå kurs

Kära dagbok,

Det finns väl inget utryck som för en att låta så mycket som en universitetslärare som ”reflektion”. Det skulle vara om ordet står i plural och stavas med x. Jag går en fortsättningskurs i högskolepedagogik just nu, och det får mig att tänka på lärande.

En positiv bieffekt är att den låter mig resa till Alnarp, ett av SLU:s andra campusområden. Det är fint där.

För det första är jag förvånad över hur mycket som sitter kvar från grundkursen jag gick som doktorand. Men för säkerhets skull, för jag hade känslan av att jag lärde mig ganska lite då, skummade jag igenom Biggs & Tang (2011), kursboken för SLU:s grundkurs i högskolepedagogik. Den håller hårt på constructive alignment av mål, aktiviteter och examination: idén att en bra kurs först definierar var studenterna ska kunna i slutet av den, och sedan övar och examinerar den just detta. Det är viktigt att precisera just vad ”kunna” betyder i sammanhanget: ska studenterna kunna förklara begrepp, ska de kunna lösa problem, eller ska de kunna bygga en maskin? I så fall bör de få öva sig på att förklara, eller bygga maskiner, och examineras på sin förmåga att förklara, eller bygga maskiner. Det är en av de där förrädiskt enkla idéerna som kan leda till dramatiska förändringar om man tar den på allvar.

Jag tänker förstås tillbaka på när jag var student. En del kurser var exemplariska i att sätta oss i basgrupper där vi fick förklara begrepp för varandra eller laborationer där vi fick lösa problem. En gästföreläsare (vars namn jag glömt; hon kom från Rättsmedicinalverket, tror jag) gav en 15 minuters introduktion till sitt ämne. Sedan lät hon oss tänka ut vad vi ville veta, formulera frågor, och sedan byggde hon resten av föreläsningen kring dem. Intressant sätt att både ge studenterna ansvar och hjälpa henne tackla vår förförståelse av ämnet. Modigt också. Annat var mindre exemplariskt; många sömniga föreläsningar blev det.

Själv har jag ofta tänkt, och sagt, ungefär ”tänk om jag kunde gå tillbaka och göra om de där första årens kurser med allt jag lärt mig om att lära mig”. I viss mån är det säkert sant att jag blev bättre på att lära mig. De sista åren som student fick jag till exempel för mig att organisera mina anteckningar som färgglada tankekartor, och repetera genom att titta på delar av dem och förklara dem för mig själv. Det var säkert inte helt tokigt. Å andra sidan, mycket av det jag lärde mig om att lära mig var nog också att strategiskt och ytligt ta in det som behövdes för att lyckas med tentan. På så sätt är det kanske till och med möjligt att lära sig sämre sämre med mer erfarenhet.

Som deltagare i en kurs om pedagogik fäster en naturligtvis extra uppmärksamhet vid hur undervisningen går till. Lever lärarna som de lär? Och vilka aktiviteter kan jag snappa upp och själv använda, helst de som inte kräver att kursen designas om i grunden utan bara annan användning av den tid och de resurser som finns? Kursen har inte gjort mig besviken så långt. Den fungerar verkligen som demonstration av sitt eget innehåll, med massor av små think–pair–share-moment, tillverkning av konceptkartor i grupper, gott om tid till diskussion, och aktiviteter som låter oss använda det vi läst in oss på i förväg, så att det får förberedelsen att kännas meningsfull.

Ett par höjdpunkter från de första kurstillfällena:

Linn Areskoug från enheten för pedagogisk utveckling samt från Uppsala universitet pratade om normkritik. Rubriken var ”könsmedveten undervisning”, men som sig bör var innehållet ifrågasättande även mot den idén. Det slog mig också under föreläsningen att föreläsningsstilen till stod del bestod av att problematisera de begrepp som just introducerats med en serie exempel och öppna frågor. När syftet var att åhörarna skulle tänka över identitet och ifrågasätta saker som känns uppenbara för oss, är det kanske en bra strategi. Jag undrar om det skulle gå att presentera svåra problem inom genetik på ett liknande sätt, med betoningen på frågorna, inte svaren.

Alexis Engström från Uppsala universitet gav oss, bland annat, bokstavligt talat en lista på aktiviteter som bryter med traditionell undervisning. Det jag tyckte lät mest spännande var ”Det saknade perspektivet”: att lämna ett pass i schemat öppet och ge studenterna i uppgift att fylla det med innehåll och aktiviteter som de tycker saknas i kursen, lite som en storskalig variant av vad gästföreläsaren från Rättsmedicinalverket gjorde.

Jag hoppas få med mig några saker jag kan göra för att vara en bättre lärare, och förstå lite bättre hur lärande fungerar. Som bonus har jag i alla fall roligt.

Litteratur

Biggs J & Tang C. (2011) Teaching for quality learning at university. 4th edition. Open University Press.

If research is learning, how should researchers learn?

I’m taking a course on university pedagogy to, hopefully, become a better teacher. While reading about students’ learning and what teachers ought to do to facilitate it, I couldn’t help thinking about researchers’ learning, and what we ought to do to give ourselves a good learning environment.

Research is, largely, learning. First, a large part of any research work is learning what is already known, not just by me in particular; it’s a direct continuation of learning that takes place in courses. While doing any research project, we learn the concepts other researchers use in this specific sub-subfield, and the relations between them. First to the extent that we can orient ourselves, and eventually to be able to make a contribution that is intelligible to others who work there. We also learn their priorities, attitudes and platitudes. (Seriously, I suspect you learn a lot about a sub-subfield by trying to make jokes about it.) We also learn to do something new: perform a laboratory procedure, a calculation, or something like that.

But more importantly, research is learning about things no-one knows yet. The idea of constructivist learning theory seems apt: We are constructing new knowledge, building on pre-existing structures. We don’t go out and read the book of nature; we take the concepts and relations of our sub-subfield of choice, and graft, modify and rearrange them into our new model of the subject.

If there is something to this, it means that old clichéd phrases like ”institution of higher learning”, scientists as ”students of X”, and so on, name a deeper analogy than it might seem. It also suggests that innovations in student learning might also be good building blocks for research group management. Should we be concept mapping with our colleagues to figure out where we disagree about the definition of ”developmental pleiotropy”? It also makes one wonder why meetings and departmental seminars often take the form of sage on the stage lectures.