Endometrios och dna-metylering

Idag är det sista dagen i mars, som var endometriosmånaden. Endometrios verkar vara ett jävla elände, svårt att göra något åt och dessutom vanligt. Sjukdomen har med celldifferentiering att göra; det börjar växa livmoderliknande celler utanför livmodern, där de orsakar smärta och infertilitet. Ingen vet vad det egentligen beror på, men det verkar vara något som kommer i och med menstruationscykeln hos människor och andra primater. Livmoderslemhinnan differentieras, alltså utvecklas, varje månad oavsett om något befruktat ägg implanteras eller ej, och stöts ut vid mensen. Hos andra däggdjur händer det inte förrän det fastnar ett befruktat ägg; det verkar vara något med den här upprepade differentieringen och utstötningen som på något sätt kan gå snett och orsaka endometrios.

Den sjätte mars kom det en artikel, Genome-Wide DNA Methylation Analysis Predicts an Epigenetic Switch for GATA Factor Expression in Endometriosis  (Dyson m.fl. 2014), om dna-metylering och genreglering i endometrios. Den är en av många som går ut på att förstå vilka gener och signalvägar i celler som är inblandade i sjukdomen. Den leder inte direkt till någon behandling, men bidrar förhoppningsvis en liten del till en grund att stå på för att kunna utveckla en. Författarna har jämfört dna-metylering och genuttryck i endometriosceller och normala celler, obehandlade och behandlade med en hormoncocktail som liknar den som får livmoderslemhinnan att mogna, för att se vilka gener som verkar regleras konstigt i de sjuka cellerna. Redan tidigare finns det en lista på viktiga gener som uttrycks och metyleras annorlunda i endometrios, och författarna hittar ett gäng till, framför allt ett par gener i GATA-familjen.

Genuttryck handlar alltså om vilka gener som cellen använder och inte. Alla celltyper har samma arvsmassa, men de använder olika delar av den. Genuttryck regleras på många olika sätt, men dna-metylering är ett av de epigenetiska märken som kan vara inblandat i att reglera vissa gener. Författarna kom fram till att genuttryck skiljer sig en hel del mellan sjuka och friska celler, men framför allt blir det stora ändringar när cellerna utsätts för hormoner. Men dna-metyleringen, däremot, var relativt oförändrad av hormonbehandlingen men skilde sig mellan sjuka och friska celler.

För att sortera fram de gener som mest troligt reglerades av dna-metylering hittade de på en statistisk analys som jag tycker verkar intressant men inte är helt övertygad om att jag förstår. Det är en linjär modell av genttryck som funktion av dna-metylering vid cytosiner nära genen och en variabel som beskriver cytosinens läge i förhållande till genen (och närmaste CpG-ö). De sökte efter en statistisk interaktion mellan läge och metylering; tanken är att det är mer troligt att genen regleras av dna-metylering om metyleringen är specifik för ett visst mindre område. Interaktionsanalysen ger dem i alla fall en liten lista på extra intressanta gener, bland annat GATA-gener. De är en familj av transkriptionsfaktorer, alltså gener som i sin tur reglerar andra gener.

Författarna prövade att slå ut och överuttrycka GATA2 och GATA6 genen i endometriosceller. Det är en fantastiskt bra sak med cellkultur, att det ibland går att göra genetiska modifikationer i celler som kommer från riktiga patientprover. Det är förstås inte riktigt att experimentera med sjuka celler i sin naturliga miljö, men det är ganska nära. Högt uttryck av GATA2 verkar leda till differentiering, medan högt uttryck av GATA6 får normala celler att bete sig mer som endometriotiska celler. Tyvärr räckte det inte med att slå ner GATA6 och öka GATA2 för att få sjuka celler att bete sig som friska igen. Men de försökte i alla fall. Det finns fler gener att pröva.

Litteratur

Dyson MT, Roqueiro D, Monsivais D, Ercan CM, Pavone ME, et al. (2014) Genome-Wide DNA Methylation Analysis Predicts an Epigenetic Switch for GATA Factor Expression in Endometriosis. PLoS Genet 10(3): e1004158. doi:10.1371/journal.pgen.1004158

Inför NBIC45: hurra för pcr!

Våren är alltså min undervisningssäsong. Nu är det dags för NBIC45, Molekylärgenetik, där jag är med och håller i ett par laborationer. Det här är den av kurserna som är närmast det jag själv håller på med och dessutom roligast. Nåja, de som inte tänker syssla med genetik kanske inte tycker att det är fullt lika underhållande, men det kan ändå vara bra att veta lite om hur molekylärgenetik går till. Bland annat ska vi ta fram dna, kopiera det med polymeraskedjereaktionen och titta på produkterna på agarosgel.

Om någon av studenterna skulle leta sig hit: Här är några poster från tidigare år:

Polymeraskedjereaktionen
Att tolka agarosgel
Så går det till: att ta fram DNA och RNA, polymeraskedjereaktionen och agarosgelelektrofores.

Och här är lite inofficiell rekommenderad läsning: Dels patentet på pcr (Kary Mullis m.fl) från 1987 och ”Improved M13 phage cloning vectors and host strains: nucleotide sequences of the M13mpl8 and pUC19 vectors”, Yanisch-Peron, Veira & Messing (1985), som beskriver plasmiden pUC19 som vi använder i andra laborationen.

Om den andra kursen som börjar nu, Communicating science, har jag inte lika mycket att säga, mer än att Martins regler för vetenskapskommunikation lyder:

1. Om det överhuvudtaget är möjligt, nämn dinosaurier.

2. Påstå inte att din forskning hjälper till att bota cancer om inte din forskning faktiskt handlar om att bota cancer.

Dagens rekommendation: Soay-fårens horn

Ännu en höjdpunkt från ESEB i somras! Jag vet inte om det var planerat eller ett sammanträffande, men Susan Johnston höll det här föredraget samma dag som artikeln kom ut i Nature. Den handlar om genetisk variation för hornstorlek hos får och hur det kommer sig att det fortfarande finns någon variation, trots att naturligt urval gynnar får med stora horn. Tyvärr börjar videon en bit in i föredraget mitt i förklaringen av ett diagram, så jag har länkat till en något naturligare startpunkt en bit in, där det börjar handla om Soayfåren på S:t Kilda. Bakgrunden är som följer: naturligt urval är bra på att göra sig av med genetisk variation. Om det finns ärftlig variation för en egenskap (i fårens fall: hur stora horn de har) och om den orsakar en skillnad i reproduktiv framgång (får med stora horn får fler ungar) så borde varianterna som orsakar små horn med tiden bli utkonkurrerade. Förr eller senare borde alla får ha stora horn. Varför finns det får med små horn? Soayfårens hornstorlek bestäms till stor del av en enda genetisk variant med enkelt arv; Johnston & co har tittat på hur bra fåren överlever och hur mycket de fortplantar sig om de har varianten för små horn, varianten för stora eller är heterozygota. Det visar sig att det är heterozygoterna, de som har en kopia av varje variant, som i långa loppet har störst sammantagen reproduktiv framgång. De får färre lamm, men de lever också längre, medan får med bara varianten stora horn har sämre överlevnad och får med bara den för små har sämre fortplantning. Lyssna på föredraget för mer detaljer!

(Åter igen: hitta den långhåriga och den korthåriga Linköpingsgenetikern i publiken under frågestunden …)

Litteratur

Johnston, Susan E., et al. Life history trade-offs at a single locus maintain sexually selected genetic variation. Nature (2013).

About blogging

Dear diary,

I’ve had this blog since 2010, but it was not until last year that I started writing anything else than popular/science in Swedish. There is lots of discussion on academic blogs about whether PhD students, or any academics, should write on blogs or not and also quite a bit of fear, uncertainty and doubt going around. This is what I think: I don’t think my blog is such a big deal. It’s just a small hobby project that makes me happy. And while I hope it doesn’t hurt my research or my chances to continue doing science, I don’t think it helps them much either.

Do I have a target audience? There was recently a small survey to find what academics blog about and why; they found that most blogs were directed at peers, not for outreach. I’m not surprised. As I’ve already mentioned, my posts in Swedish are more popular/science, less technical and sometimes deal with things published in Swedish media. I think the target audience is still geeks of some kind, but not necessarily genetics geeks. My posts in English are more directed at academical things, either related to my research and work as a PhD student or about the R language. So my posts are a mix of languages and themes. Is that a problem? From a popularity or readership perspective, probably yes. I can see little reason not to split the posts to two blogs, each concentrated on one theme, except that I don’t feel like running two blogs.

Does blogging hurt me because it hurts my work? I hardly think so. First, blogging is not part of my duties at the university, and I don’t do it instead of writing, working in the lab or analysing data. I do it in the evening after work, or in the case of some posts in the morning before. I’m not convinced blogging makes me in any way a better scientist, but it can hardly make me worse. Thinking about science or how to explain it for another hour now and then can’t hurt. And yes, the time spent blogging could theoretically be spent writing papers or something, but so could theoretically the time spent at the gym, with family or friends. If we grant that academics do other things, blogging could be one of those activities. My blog is not completely disconnected from my work, but I think it’s disconnected enough to be regarded as a fun pastime.

Does blogging hurt my reputation because people might read my blog and disapprove? I don’t think that many people read my blog; actually, I know that not many people do. Still, it is certainly possible that some of the readers might be important to my career and that they don’t like what they see. It will be found when people look me up with a search engine. Maybe someone thinks that I’m wasting my time, or maybe I’ve written something controversial — or more likely, something stupid. I think and say things that are mistaken all the time, and some of those mistakes might end up in a blog post. The point is, though, that expressing my opinion about things I care about is not something I do because I think it’ll further my career. I do it because I want to. If my writing is successful, the things on my blog will be the kinds of things I honestly know, think and believe about science.

More fun with %.% and %>%

The %.% operator in dplyr allows one to put functions together without lots of nested parentheses. The flanking percent signs are R’s way of denoting infix operators; you might have used %in% which corresponds to the match function or %*% which is matrix multiplication. The %.% operator is also called chain, and what it does is rearrange the call to pass its left hand side on as a parameter to the right hand side function. As noted in the documentation this makes function calls read from left to right instead of inside and out. Yesterday we we took a simulated data frame, called data, and calculated some summary statistics. We could put the entire script together with %.%:

library(dplyr)
data %.%
    melt(id.vars=c("treatment", "sex")) %.%
    group_by(sex, treatment, variable) %.%
    summarise(mean(value))

I haven’t figured out what would be the best indentation here, but I think this looks pretty okay. Of course it works for non-dplyr functions as well, but they need to take the input data as their first argument.

data %.% lm(formula=response1 ~ factor(sex)) %.% summary()

As mentioned, dplyr is not the only package that has something like this, and according to a comment from Hadley Wickham, future dplyr will use the magrittr package instead, a package that adds piping to R. So let’s look at magrittr! The magrittr %>% operator works much the same way, except it allows one to put ”.” where the data is supposed to go. This means that the data doesn’t have to be the first argument to the function. For example, we can do this, which would give an error with dplyr:

library(magrittr)
data %>% lm(response1 ~ factor(sex), .) %>% summary()

Moreover, Conrad Rudolph has used the operators %.%, %|>% and %|% in his own package for functional composition, chaining and piping. And I’m sure he is not the only one; there are several more packages that bring more new ways to define and combine functions into R. I hope I will revisit this topic when I’ve gotten used to it and decided what I like and don’t like. This might be confusing for a while with similar and rather cryptic operators that do slightly different things, but I’m sure it will turn out to be a useful development.

Using R: quickly calculating summary statistics (with dplyr)

I know I’m on about Hadley Wickham‘s packages a lot. I’m not the president of his fanclub, but if there is one I’d certainly like to be a member. dplyr is going to be a new and improved ddply: a package that applies functions to, and does other things to, data frames. It is also faster and will work with other ways of storing data, such as R’s relational database connectors. I use plyr all the time, and obviously I want to start playing with dplyr, so I’m going to repeat yesterday’s little exercise with dplyr. Readers should be warned: this is really just me playing with dplyr, so the example will not be particularly profound. The post at the Rstudio blog that I just linked contains much more information.

So, here comes the code to do the thing we did yesterday but with dplyr:

## The code for the toy data is exactly the same
data <- data.frame(sex = c(rep(1, 1000), rep(2, 1000)),
                   treatment = rep(c(1, 2), 1000),
                   response1 = rnorm(2000, 0, 1),
                   response2 = rnorm(2000, 0, 1))

## reshape2 still does its thing:
library(reshape2)
melted <- melt(data, id.vars=c("sex", "treatment"))

## This part is new:
library(dplyr)
grouped <- group_by(melted, sex, treatment)
summarise(grouped, mean=mean(value), sd=sd(value))

When we used plyr yesterday all was done with one function call. Today it is two: dplyr has a separate function for splitting the data frame into groups. It is called group_by and returns the grouped data. Note that no quotation marks or concatenation were used when passing the column names. This is what it looks like if we print it:

Source: local data frame [4,000 x 4]
Groups: sex, treatment, variable

   sex treatment  variable       value
1    1         1 response1 -0.15668214
2    1         2 response1 -0.40934759
3    1         1 response1  0.07103731
4    1         2 response1  0.15113270
5    1         1 response1  0.30836910
6    1         2 response1 -1.41891407
7    1         1 response1 -0.07390246
8    1         2 response1 -1.34509686
9    1         1 response1  1.97215697
10   1         2 response1 -0.08145883

The grouped data is still a data frame, but it contains a bunch of attributes that contain information about grouping.

The next function is a call to the summarise function. This is a new version of a summarise function similar to one in plyr. It will summarise the grouped data in columns given by the expressions you feed it. Here, we calculate mean and standard deviation of the values.

Source: local data frame [8 x 5]
Groups: sex, treatment

  sex treatment  variable         mean        sd
1   1         1 response1  0.021856280 1.0124371
2   1         1 response2  0.045928150 1.0151670
3   1         2 response1 -0.065017971 0.9825428
4   1         2 response2  0.011512867 0.9463053
5   2         1 response1 -0.005374208 1.0095468
6   2         1 response2 -0.051699624 1.0154782
7   2         2 response1  0.046622111 0.9848043
8   2         2 response2 -0.055257295 1.0134786

Maybe the new syntax is slightly clearer. Of course, there are alternative ways of expressing it, one of which is pretty interesting. Here are two equivalent versions of the dplyr calls:

summarise(group_by(melted, sex, treatment, variable),
          mean=mean(value), sd=sd(value))

melted %.% group_by(sex, treatment, variable) %.%
       summarise(mean=mean(value), sd=sd(value))

The first one is nothing special: we’ve just put the group_by call into summarise. The second version, though, is a strange creature. dplyr uses the operator %.% to denote taking what is on the left and putting it into the function on the right. Reading from the beginning of the expression we take the data (melted), push it through group_by and pass it to summarise. The other arguments to the functions are given as usual. This may seem very alien if you’re used to R syntax, or you might recognize it from shell pipes. This is not the only attempt make R code less nested and full of parentheses. There doesn’t seem to be any consensus yet, but I’m looking forward to a future where we can write points-free R.

Using R: quickly calculating summary statistics from a data frame

A colleague asked: I have a lot of data in a table and I’d like to pull out some summary statistics for different subgroups. Can R do this for me quickly?

Yes, there are several pretty convenient ways. I wrote about this in the recent post on the barplot, but as this is an important part of quickly getting something useful out of R, just like importing data, I’ll break it out into a post of its own. I will present a solution that uses the plyr and reshape2 packages. You can do the same with base R, and there’s nothing wrong with base R, but I find that plyr and reshape2 makes things convenient and easy to remember. The apply family of functions in base R does the same job as plyr, but with a slightly different interface. I strongly recommend beginners to begin with plyr or the apply functions, and not what I did initially, which was nested for loops and hard bracket indexing.

We’ll go through and see what the different parts do. First, simulate some data. Again, when you do this, you usually have a table already, and you can ignore the simulation code. Usually a well formed data frame will look something this: a table where each observation is a unit such as an individual, and each column gives the data about the individual. Here, we imagine two binary predictors (sex and treatment) and two continuous response variables.

data <- data.frame(sex = c(rep(1, 1000), rep(2, 1000)),
                   treatment = rep(c(1, 2), 1000),
                   response1 = rnorm(2000, 0, 1),
                   response2 = rnorm(2000, 0, 1))
head(data)
  sex treatment   response1   response2
1   1         1 -0.15668214 -0.13663012
2   1         2 -0.40934759 -0.07220426
3   1         1  0.07103731 -2.60549018
4   1         2  0.15113270  1.81803178
5   1         1  0.30836910  0.32596016
6   1         2 -1.41891407  1.12561812

Now, calculating a function of the response in some group is straightforward. Most R functions are vectorised by default and will accept a vector (that is, a column of a data frame). The subset function lets us pull out rows from the data frame based on a logical expression using the column names. Say that we want mean, standard deviation and a simple standard error of the mean. I will assume that we have no missing values. If you have, you can add na.rm=T to the function calls. And again, if you’ve got a more sophisticated model, these might not be the standard errors you want. Then pull them from the fitted model instead.

mean(subset(data, sex == 1 & treatment == 1)$response1)

sd(subset(data, sex == 1 & treatment == 1)$response1)

sd(subset(data, sex == 1 & treatment == 1)$response1)/
  sqrt(nrow(subset(data, sex == 1 & treatment == 1)))

Okay, but doing this for each combination of the predictors and responses is no fun and requires a lot of copying and pasting. Also, the above function calls are pretty messy with lots of repetition. There is a better way, and that’s where plyr and reshape2 come in. We load the packages. The first time you’ll have to run install.packages, as usual.

library(plyr)
library(reshape2)

First out, the melt function from rehape2. Look at the table above. It’s reasonable in many situations, but right now, it would be better if we put both the response variables in the same column. If it doesn’t seem so useful, trust me and see below. Melt will take all the columns except the ones we single out as id variables and put them in the same column. It makes sense to label each row with the sex and treatment of the individual. If we had an actual unit id column, it would go here as well:

melted <- melt(data, id.vars=c("sex", "treatment"))

The resulting ”melted” table looks like this. Instead of the response variables separately we get a column of values and a column indicating which variable the value comes from.

  sex treatment  variable       value
1   1         1 response1 -0.15668214
2   1         2 response1 -0.40934759
3   1         1 response1  0.07103731
4   1         2 response1  0.15113270
5   1         1 response1  0.30836910
6   1         2 response1 -1.41891407

Now it’s time to calculate the summary statistics again. We will use the same functions as above to do the actual calculations, but we’ll use plyr to automatically apply them to all the subsets we’re interested in. This is sometimes called the split-apply-combine approach: plyr will split the data frame into subsets, apply the function of our choice, and then collect the results for us. The first thing to notice is the function name. All the main plyr functions are called something with -ply. The letters stand for the input and return data type: ddply works on a data frame and returns a data frame. It’s probably the most important member of the family.

The arguments to ddply are the data frame to work on (melted), a vector of the column names to split on, and a function. The arguments after the function name are passed on to the function. Here we want to split in subsets for each sex, treatment and response variable. The function we apply is summarise, which makes a new data frame with named columns based on formulas, allowing us to use the column names of the input data frame in formulas. In effect it does exactly what the name says, summarises a data frame. And in this instance, we want to calculate the mean, standard deviation and standard error of the mean, so we use the above function calls, using value as the input. Run the ddply call, and we’re done!

ddply(melted, c("sex", "treatment", "variable"), summarise,
      mean = mean(value), sd = sd(value),
      sem = sd(value)/sqrt(length(value)))
  sex treatment  variable         mean        sd        sem
1   1         1 response1  0.021856280 1.0124371 0.04527757
2   1         1 response2  0.045928150 1.0151670 0.04539965
3   1         2 response1 -0.065017971 0.9825428 0.04394065
4   1         2 response2  0.011512867 0.9463053 0.04232006
5   2         1 response1 -0.005374208 1.0095468 0.04514830
6   2         1 response2 -0.051699624 1.0154782 0.04541357
7   2         2 response1  0.046622111 0.9848043 0.04404179
8   2         2 response2 -0.055257295 1.0134786 0.04532414

Morning coffee: short papers

kaffe_block

I’m going to quote in full the ”methods summary” from the latest FTO/IRX3 Nature paper (Smemo & al 2014); I think the paper is great and I’m only using it as an example of the format of Nature letters:

For 4C-seq, chromatin was digested with DpnII and Csp6I. Captured DNA was amplified using promoter-specific primers and deep sequenced.
For 3C, nuclei were digested with HindIII. Primer quality was assessed using serial dilutions of BACs encompassing the regions of interest (RP23-268O10, RP23-96F3). The average of four independent experiments is represented graphically (Extended data Fig 2c).

For anyone who hasn’t read the paper: it is not only about chromatin capture. The results rely on gene expression, reporter experiments in mice, phenotyping of knockout mice etc etc etc.

I read quite a lot of Nature and Science papers. Yes, one should be critical of the role of glamorous journals, but they publish a lot of things that either is interesting to me or get a lot of media attention. But the papers are not really papers, are they? They are too short to fit all the details, even with the additional online methods part. What does it say about a journal that it forces authors to cut out the methods, the most important section for judging reliability of the results? What does it say about me as a reader that I often don’t bother going to the supplementary material to read them? It’s not very flattering for any of us, I’m sure. If you suffer from such a shortage of paper that you have to remove a section of each article and hide it online it should be the discussion, not the methods.

Literature

Smemo & al (2014) Obesity-associated variants within FTO form long-range functional connections with IRX3.
Nature

Dagens rekommendation: Vetenskapsmormor

Eller -farmor. Grandma Got STEM är en blogg med äldre kvinnor som sysslar med vetenskap, teknik och matematik. Bara för att påminna om att det finns massor av kvinnor som pysslar med vetenskap och det är inget nytt. En del av dem har hunnit bli mor- och farmödrar. ”Förklara så att din mormor begriper”, är inget vidare bra exempel.

Och apropå det, min favorit-post-it-lapp fotograferad av Adam Gaffin.

På skylten står det: Can you solve one of our puzzles? Can you explain it to your mom?

Någon har satt dit en post-it-lapp: MY MOM HAS A PHD IN MATH

(Dessutom: Notera den fåniga lateraliseringen av hjärnan i annonsen.)

Dagens rekommendation: två berättelser bakom en artikel

Metagenomik handlar om att använda modern massivt parallell sekvensering för att studera vilka gener som finns i en viss miljö. Ta jord till exempel: jorden är full med olika organismer, både bakterier, svampar, små djur, växter och så vidare. Ett sätt att ta reda på vad som finns där är att isolera dna från jorden, oavsett vilka varelser det kommer ifrån, sekvensera det och försöka identifiera var de olika sekvenserna kommer ifrån. Tackling soil diversity with the assembly of large, complex metagenomes (Chuang Howe m.fl. 2014) är ett exempel på detta: författarna har hittat på en rad nya metoder för att passa ihop sekvenserna, dela upp upp dem och hantera mängden data. (Det är sällan i biologi som en får ihop en riktigt stor mängd data, men det här är ett sådant fall.) Både C. Titus Brown, som lett gruppen och Adina Chuang Howe, förstaförfattaren till artikeln har skrivit öppenhjärtiga bloggposter om hur artikeln kom till. Läs dem och titta bakom kulisserna!