-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path1-NCBI_GEO_mining.Rmd
387 lines (269 loc) · 10.8 KB
/
1-NCBI_GEO_mining.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
---
title: "test"
output: html_document
---
# 1 Introduction
The goal of this notebook is to reanalyze a published microarray data set. Here, we will use data from [this study](http://www.ncbi.nlm.nih.gov/pubmed/19732725), which contains data on pancreatic cancer samples. We will first reproduce the corresponding figure in the paper, then perform some exploratory data analysis.
## 2 Load libraries
These commads will load the libraries that will be used later in this analysis. If any of these result in errors, we need to first install those libraries.
```{r cache=TRUE}
library(GEOquery)
library(mygene)
library(ggplot2)
library(dplyr)
library(reshape)
library(repr)
```
## 3 Retrieve and prepare data
### 3.1 Retrieve data from NCBI GEO
[NCBI GEO](http://www.ncbi.nlm.nih.gov/geo/a) is one of the primary repositories for gene expression data. In this step, you are contacting the GEO server to download data for `GDS4102`, the data set ID for the pancreatic tumor data set we are studying.
```{r cache=TRUE}
require(GEOquery)
gds <- getGEO("GDS4102")
```
### 3.2 Extract expression data object
The overall expression data object will be read into the variable `eset` (for "expression set").
```{r cache=TRUE}
eset <- GDS2eSet(gds)
print(eset)
```
These warnings need to be checked out. Doing a search for [GDS2eSet "In readLines(con, 1): seek on a gzfile connection returned an internal error"](https://www.google.com/search?q=GDS2eSet+%22In+readLines%28con%2C+1%29%3A+seek+on+a+gzfile+connection+returned+an+internal+error%22&ie=utf-8&oe=utf-8) leads to [this page](https://support.bioconductor.org/p/41581/), which states:
> The warning messages are just that. Things will work fine even with the warnings.
Clearly, let's do some sanity checking...
### 3.3 Sanity check
Let's read the data matrix into a variable called `dat`, in which each row is a probeset ID (generally corresponding to one transcript), and each column is a sample. Then, let's look at the `head` of that data matrix and the overall dimensions.
```{r}
require(Biobase)
dat <- exprs(eset)
head(dat)
dim(dat)
```
**Note**: This finding above is very odd -- we have data for 52 samples here, but paper reports 55 samples...
Nevertheless, we push on....
```{r}
summary(as.numeric(dat))
```
### 3.4 Find the relevant probe set IDs
Here, we use a library called `mygene` to query for the relevant reporters.
```{r}
require(mygene)
queryGene <- mygene::query(q="FKBP51",species="human")
queryGene$hits
```
Confusingly, both `FKBP5` and `FKBP4` have been referred to as `FKBP51` in the past. Referencing the paper, it appears that `FKBP5` (Entrez Gene ID 2289) is the correct gene.
We then get information of the `reporter` for this gene entry from `mygene`.
```{r}
queryGene <- getGene("2289", fields="symbol,entrezgene,reporter")
print(queryGene)
selectedProbeIDs <- queryGene$reporter$`HG-U133_Plus_2`
selectedProbeIDs
```
### 3.5 Extract expression data
Given the `selectedProbeIDs` found above, extract the relevant expression data from the entire data matrix.
```{r}
selectedDat <- dat[rownames(dat) %in% selectedProbeIDs,]
selectedDat
dim(selectedDat)
```
## 4 Plotting
### 4.1 Scatter plot
There are two main methods for plotting in R. One is the built-in `plot` command, and one is the `ggplot2` library. For the first plots, both methods are shown. Moving forward, you are welcome to use whichever library you choose.
For the first plot, we will simply create a scatter plot corresponding to the first probe set we retrieved.
#### `plot` method
```{r}
i <- 1
probeID <- rownames(selectedDat)[i]
plot(selectedDat[i,],main=probeID)
```
#### `ggplot2` method
The most important thing to note is that ``ggplot2`` expects data to be in a data frame.
```{r}
selectedDatDF <- data.frame(idx=1:(dim(selectedDat)[2]),exp=selectedDat[i,])
head(selectedDatDF)
dim(selectedDatDF)
require(ggplot2)
ggplot(selectedDatDF, aes( x = idx, y = exp )) +
geom_point() +
ggtitle(probeID)
```
### 4.2 Customizing with color
The plots above aren't particularly useful because we can't see which samples correspond to tumor and which are the normal controls. Here, we extract the phenotype data (or `pdata`) from our `eset` object.
```{r}
pData(eset)
table(pData(eset)$tissue)
```
#### `plot` method
```{r}
plot(selectedDat[i,],main=probeID,col=pData(eset)$tissue)
```
#### `ggplot` method
```{r}
selectedDatDF$tissue <- pData(eset)$tissue
head(selectedDatDF)
ggplot(selectedDatDF, aes( x = idx, y = exp, colour = tissue )) +
geom_point() +
ggtitle(probeID)
```
### 4.3 Barplots
Another way to summarize these data is to use barplots. (From here, we are only using ``ggplot``.)
The first step is the summarize the data. This section has intermediate-level transformations using the library `dplyr`. For the moment, as long as you understand the input and output of this section, don't worry too much about how it's done.
```{r}
require(dplyr)
grouped <- group_by(selectedDatDF,tissue)
head(grouped)
dim(grouped)
```
Now, we need to summarize the data table according to normal and tumor expression values.
```{r}
selectedDatDFSummarized <- summarize(grouped, mean = mean(exp), sd = sd(exp), n = length(exp))
selectedDatDFSummarized$sem <- selectedDatDFSummarized$sd / sqrt(selectedDatDFSummarized$n)
selectedDatDFSummarized
ggplot(selectedDatDFSummarized,aes(x = tissue,y = mean)) +
geom_bar(stat = "identity") +
ggtitle(probeID)
```
We can also add error bars using `geom_errorbar`:
```{r}
ggplot(selectedDatDFSummarized,aes(x = tissue,y = mean)) +
geom_bar(stat="identity") +
geom_errorbar(aes(ymin = mean - sem, ymax = mean + sem)) +
ggtitle(probeID)
```
Now, let's put all the code we've worked about above in a `for` loop so we can easily generate charts for all the probe sets of interest.
```{r}
for( i in 1:dim(selectedDat)[1] ) {
probeID <- rownames(selectedDat)[i]
selectedDatDF <- data.frame(idx = 1:(dim(selectedDat)[2]), exp = selectedDat[i, ])
selectedDatDF$tissue <- pData(eset)$tissue
grouped <- group_by(selectedDatDF, tissue)
selectedDatDFSummarized <- summarize(grouped, mean = mean(exp), sd = sd(exp), n = length(exp))
selectedDatDFSummarized$sem <- selectedDatDFSummarized$sd / sqrt(selectedDatDFSummarized$n)
print(
ggplot(selectedDatDFSummarized,aes(x = tissue,y = mean)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = mean - sem, ymax = mean + sem)) +
ggtitle(probeID)
)
}
```
Note that the third chart above for `224856_at` appears to be very similar to Figure 4D in the paper:
<img src="https://www.dropbox.com/s/zxqe52nt7h5uomf/2016-03-23_15-58-42.jpg?dl=1">

### 4.4 Dot plots
Since there really aren't that many data points here, another way to visualize these data is a dot plot.
* Google search [ggplot dot plot](https://www.google.com/search?q=ggplot+dot+plot)
* [ggplot2 dot plot : Quick start guide](http://www.sthda.com/english/wiki/ggplot2-dot-plot-quick-start-guide-r-software-and-data-visualization)
```{r}
ggplot(selectedDatDF, aes(x = factor(tissue), y = exp)) +
geom_dotplot(binaxis = "y",stackdir = "center") +
ggtitle(probeID)
```
## 5 Exploratory data analysis
What is exploratory data analysis? Excerpted from http://www.itl.nist.gov/div898/handbook/eda/section1/eda11.htm:
> Exploratory Data Analysis (EDA) is an approach/philosophy for data analysis
> that employs a variety of techniques (mostly graphical) to
>
> * maximize insight into a data set;
> * uncover underlying structure;
> * extract important variables;
> * detect outliers and anomalies;
> * test underlying assumptions;
> * develop parsimonious models; and
> * determine optimal factor settings.
Here, we will use several analysis and visualizations to explore this data set in an unbiased fashion.
### 5.1 Cleaning the data
```{r}
head(dat)
dim(dat)
summary(dat)
```
Look at all those `NA`s -- definitely need to remove those. First, let's do this with a `for` loop.
```{r}
# record the start time
startTime <- proc.time()
naProbeSets <- c()
for(i in 1:dim(dat)[1]){
naProbeSets[i] <- sum(is.na(dat[i, ]))
}
sum(naProbeSets != 0)
# output time since start time
print(proc.time() - startTime)
```
Now, let's use the same thing using the `apply` command
```{r}
# record the start time
startTime <- proc.time()
naProbeSets2 <- apply(dat, 1, function(x) {sum(is.na(x))})
sum(naProbeSets2 != 0)
# output time since start time
print(proc.time() - startTime)
```
The two vectors above (`naProbeSets` and `naProbeSets2`) have the same number of nonzero values. Now, explictly confirm that they are the same.
```{r}
sum(naProbeSets != naProbeSets2)
```
Finally, remove all lines with NA values
```{r}
datNoNa <- dat[naProbeSets == 0, ]
dim(datNoNa)
```
### 5.2 Checking normalization
We want to plot the distribution of values for each array:
* Google search [ggplot histogram distribution](https://www.google.com/search?q=ggplot+distributions&ie=utf-8&oe=utf-8#safe=off&q=ggplot+histogram+distribution)
* http://www.cookbook-r.com/Graphs/Plotting_distributions_%28ggplot2%29/
```{r}
df <- as.data.frame(datNoNa)
ggplot(df, aes(x = GSM414924)) + geom_histogram()
```
Not looking too informative -- let's try log transforming the data.
```{r}
dfLog <- log2(df)
ggplot(dfLog, aes(x = GSM414924)) + geom_histogram()
```
If we want to overlay all histograms together, we need to `melt` our data frame into a new dataframe that ggplot will expect.
```{r}
require(reshape)
print("BEFORE:")
head(dfLog)
dfLog2 = melt(dfLog, variable_name = "Sample")
print("AFTER:")
head(dfLog2)
```
Then, plot using ``ggplot``:
```{r}
ggplot(dfLog2, aes(x = value, color = Sample)) + geom_density()
```
We can also plot the distributions using a boxplot:
```{r}
ggplot(dfLog2, aes(x = Sample, y = value)) +
geom_boxplot()
ggplot(dfLog2, aes(x = Sample, y = value)) +
geom_boxplot() +
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5))
```
### 5.3 Heat map
try a random sampling of 1000 probe sets
```{r, fig.width=10,fig.height=10}
colnames(dfLog)<-paste(pData(eset)$sample,pData(eset)$tissue)
heatmap(as.matrix(sample_n(dfLog,1000)))
```
Isolate the 1000 most variable probe sets
```{r, fig.width=10,fig.height=10}
probeSetVariance <- apply(dfLog,1,var)
variableProbeSets <- order(probeSetVariance,decreasing = TRUE)[1:1000]
dfLogVariable <- dfLog[variableProbeSets, ]
heatmap(as.matrix(dfLogVariable))
```
### 5.4 Differential expression analysis
```{r}
diffExpP <- c()
for(i in 1:dim(dfLog)[1]) {
class1Exp <- dfLog[i, pData(eset)$tissue == "normal"]
class2Exp <- dfLog[i, pData(eset)$tissue == "tumor"]
diffExpP[i] <- t.test(class1Exp, class2Exp)$p.value
}
```
HOMEWORK: write a new version of the code block above using the `apply` function.
```{r, fig.width=10,fig.height=10}
heatmap(as.matrix(dfLog[diffExpP < 0.00001,]))
```