-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlab_r.Rmd
More file actions
347 lines (257 loc) · 12 KB
/
Copy pathlab_r.Rmd
File metadata and controls
347 lines (257 loc) · 12 KB
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
---
title: "Intro to R"
subtitle: "Workshop on ggplot"
author: "`r paste0('<b>Lokesh Mano</b> • ',format(Sys.time(), '%d-%b-%Y'))`"
output:
bookdown::html_document2:
toc: true
toc_float: true
toc_depth: 4
number_sections: true
theme: flatly
highlight: tango
df_print: default
code_folding: "none"
self_contained: false
keep_md: false
encoding: 'UTF-8'
css: "assets/lab.css"
---
```{r, include=FALSE}
hooks = knitr::knit_hooks$get()
hook_foldable = function(type) {
force(type)
function(x, options) {
res = hooks[[type]](x, options)
if (isFALSE(options[[paste0("fold.", type)]])) return(res)
paste0(
"<details><summary>", type, "</summary>\n\n",
res,
"\n\n</details>"
)
}
}
knitr::knit_hooks$set(
output = hook_foldable("output"),
plot = hook_foldable("plot")
)
```
```{r,child="assets/header-lab.Rmd"}
```
```{r,include=FALSE}
# data handling
library(dplyr)
library(tidyverse)
library(kableExtra)
#library(stringr)
# plotting
library(ggplot2)
#library(biomaRt) # annotation
#library(DESeq2) # rna-seq
#library(edgeR) # rna-seq
```
R is a programming language for statistical computing, and data wrangling. It is open-source, widely used in data science, has a wide range of functions and algorithms for graphing and data analyses.
We will use R in this course for generating plots from different biological data that are of higher quality and standard for publications. To do this, you will brush-up your memory on some important aspects of R that are important for this course below:
**Before starting with the lab sessions of the entire course, you must have downloaded all the necessary files from [here](lab_download.html) and make sure that the directory tree looks similar to the one displayed in that page**
In that case, you can proceed with the exercise now and remember to have fun :)
# Input/Output
Input and output of data and images is an important aspect with data analysis.
## Text
Data can come in a variety of formats which needs to be read into R and converted to an R data type.
Text files are the most commonly used input. Text files can be read in using the function `read.table`. We have a sample file to use: **iris.txt**.
```{r}
dfr <- read.table("data/metadata_raw.csv",sep = ";", header=TRUE,stringsAsFactors=F)
```
This reads in a tab-delimited text file with a header. The argument `sep='\t'` is set by default to specify that the delimiter is a tab. `stringsAsFactors=F` setting ensures that character columns are not automatically converted to factors.
It's always a good idea to check the data after import.
```{r}
head(dfr)
```
```{r}
str(dfr)
```
Check `?read.table` for other wrapper functions to read in text files.
Let's filter this data.frame and create a new data set.
```{r}
dfr1 <- dfr[dfr$Time == "t0",]
```
And we can write this as a text file.
```{r,eval=FALSE}
write.table(dfr1,"iris-setosa.txt",sep="\t",row.names=F,quote=F)
```
`sep="\t"` sets the delimiter to tab. `row.names=F` denotes that rownames should not be written. `quote=F` specifies that doubles must not be placed around strings.
# Data-Frames
You have probably learnt about `data.frame` in your previous course and this is the most important data structure for generating plots using `ggplot`. So, below you have some quick exercises on how to work with Data-Frames.
Vectors positions can be accessed using `[]`. R follows 1-based indexing, meaning that the indexing starts at 1.
Data-frame or matrix positions can be accessed using `[]` specifying row and column like `[row,column]`.
```{r}
dfr <- data.frame(x = 1:3, y = c("a", "b", "c"))
dfr
dfr[1,]
dfr[,1]
dfr[2,2]
```
The function `cbind()` is used to join two data-frames column-wise.
```{r}
dfr1 <- data.frame(x = 1:3, y = c("a", "b", "c"))
dfr2 <- data.frame(p = 4:6, q = c("d", "e", "f"))
dfr1
dfr2
cbind(dfr1,dfr2)
```
Similarly, `rbind()` is used to join two data-frames row-wise.
```{r}
dfr1 <- data.frame(x = 1:3, y = c("a", "b", "c"))
dfr2 <- data.frame(x = 4:6, y = c("d", "e", "f"))
dfr1
dfr2
rbind(dfr1,dfr2)
```
Two data-frames can be merged based on a shared column using the `merge()` function.
```{r}
dfr1 <- data.frame(x = 1:4, p = c("a", "b", "c","d"))
dfr2 <- data.frame(x = 3:6, q = c("l", "m", "n","o"))
dfr1
dfr2
merge(dfr1,dfr2,by="x")
merge(dfr1,dfr2,by="x",all.x=T)
merge(dfr1,dfr2,by="x",all.y=T)
merge(dfr1,dfr2,by="x",all=T)
```
# Data formats
In terms of the R (and other similar programming languages), the data can be viewed or stored in two main formats! They are called `wide` and `long` formats. Below you will see what exactly they stand for and why is it important for plotting in ggplot.
## Wide format
A quick preview:
**Counts Table**
```{r, echo=FALSE}
gc <- read.table("data/counts_raw.txt", header = T, row.names = 1, sep = "\t")
kable(gc[c(1:6),c(1:4)]) %>%
kable_styling(bootstrap_options = "striped", full_width = F)
```
And we usually have our metadata related to the samples in another table like below:
**Metadata Table**
```{r, echo=FALSE}
md <- read.table("data/metadata_raw.csv", header = T, sep = ";")
kable(md[c(1:4),]) %>%
kable_styling(bootstrap_options = "striped", full_width = F)
```
* Wide format data is called “wide” because it typically has a lot of columns which stretch widely across the page or your computer screen.
* Most of us are familiar with looking at wide format data
+ It is convenient and we are more used to looking at data this way in our Excel sheets.
+ It often lets you see more of the data, at one time, on your screen
## Long format
Below is glimpse how the long format of the same data look like:
```{r echo=FALSE}
samples <- colnames(gc[,c(1:4)])
gc[c(1:6),c(1:4)] %>%
rownames_to_column(var = "Gene") %>%
gather(Samples, count, -Gene) %>%
head(10) %>%
kable() %>%
kable_styling(bootstrap_options = "striped", full_width = F)
```
Or to be even more complete and precise:
```{r echo=FALSE}
samples <- colnames(gc[,c(1:4)])
gc[c(1:6),c(1:4)] %>%
rownames_to_column(var = "Gene") %>%
gather(Sample_ID, count, -Gene) %>%
full_join(md[c(1:4),], by = "Sample_ID") %>%
select(Sample_ID, everything()) %>%
select(-c(Gene,count), c(Gene,count)) %>%
head(10) %>%
kable() %>%
kable_styling("striped", full_width = F)
```
* Long format data is typically less familiar to most humans
+ It seems awfully hard to get a good look at all (or most) of it
+ It seems like it would require more storage on your hard disk
+ It seems like it would be harder to enter data in a long format
## Which is better?
* Well, there are some contexts where putting things in wide format is computationally efficient because you can treat data in a matrix format and to efficient matrix calculations on it.
* However, adding data to wide format data sets is very hard:
1. It is very difficult to conceive of analytic schemes that apply generally across all wide-format data sets.
2. Many tools in R want data in long format **like ggplot**
3. The long format for data corresponds to the relational model for storing data, which is the model used in most modern data bases like the SQL family of data base systems.
* A more technical treatment of wide versus long data requires some terminology:
- <span style="color:blue">Identifier variables</span> are often categorical things that cross-classify observations into categories.
- <span style="color:red">Measured variables</span> are the names given to properties or characteristics that you can go out and measure.
- <span style="color:orange">Values</span> are the values that you measure are record for any particular measured variable.
* In any particular data set, what you might want to call an <span style="color:blue">Identifier variables</span> versus a <span style="color:red">Measured variables</span> can not always be entirely clear.
- Other people might choose to define things differently.
* However, to my mind, it is less important to be able to precisely recognize these three entities in every possible situation (where there might be some fuzziness about which is which)
* And it is more important to understand how <span style="color:blue">Identifier variables</span>, <span style="color:red">Measured variables</span>, and <span style="color:orange">Values</span> interact and behave when we are transforming data between wide and long formats.
# Conversion between formats
As for the biological data analysis, to be able to use tools such as **ggplot**, in simple terms we should learn to convert our data:
As per our previous examples: We should learn to convert
**From this format**
```{r, echo=FALSE}
gc <- read.table("data/counts_raw.txt", header = T, row.names = 1, sep = "\t")
kable(gc[c(1:6),c(1:4)]) %>%
kable_styling(bootstrap_options = "striped", full_width = F) %>%
row_spec(1:6, color = "orange") %>%
column_spec(1, color = "red") %>%
row_spec(0, bold = T, color = "blue")
```
**To this format**
```{r echo=FALSE}
samples <- colnames(gc[,c(1:4)])
gc[c(1:6),c(1:4)] %>%
rownames_to_column(var = "Gene") %>%
gather(Sample_ID, count, -Gene) %>%
full_join(md[c(1:4),], by = "Sample_ID") %>%
select(Sample_ID, everything()) %>%
select(-c(Gene,count), c(Gene,count)) %>%
head(10) %>%
kable() %>%
kable_styling("striped", full_width = F) %>%
column_spec(1:5, color = "blue") %>%
column_spec(6, color = "red")%>%
column_spec(7, color = "orange")
```
Here we will only cover the conversion from `wide` to `long`, as this is more relevant to us. For the other way around, one can look into `spread()` from the `tidyr` package.
## Using reshape2
By using the `melt()` function from the **reshape2** package we can convert the wide-formatted data into long-formatted data! Here, to combine the metadata table to the gene counts table, we will also use the `merge()` function like we did before!
```{r}
library(reshape2)
gc <- read.table("data/counts_raw.txt", header = T, row.names = 1, sep = "\t")
md <- read.table("data/metadata_raw.csv", header = T, sep = ";")
rownames(md) <- md$Sample_ID
#merging gene counts table with metadata
merged_data_wide <- merge(md, t(gc), by = 0)
#removing redundant columns
merged_data_wide$Row.names <- NULL
merged_data_long <- melt(merged_data_wide, id.vars = c("Sample_ID","Sample_Name","Time","Replicate","Cell"), variable.name = "Gene", value.name = "count")
head(merged_data_long)
```
## Using tidyr
If you are more familiar with using `tidyverse` or `tidyr` packages, you can combine tables by `join()` and then use `gather()` to make long formatted data in the same command. This is a powerful and more cleaner way of dealing with data in R.
```{r, warning=FALSE, message=FALSE}
library(tidyverse)
gc_long <- gc %>%
rownames_to_column(var = "Gene") %>%
gather(Sample_ID, count, -Gene) %>%
full_join(md, by = "Sample_ID") %>%
select(Sample_ID, everything()) %>%
select(-c(Gene,count), c(Gene,count))
gc_long %>%
head(10)
```
# Exercise
<i class="fas fa-clipboard-list"></i> Task Here in this exercise we have used the `counts_raw.txt` file, you can try to make similar R objects for each of the other three counts (`counts_filtered.txt`, `counts_vst.txt` and `counts_deseq2.txt`) in `long format`. So for example you would have `gc_filt`, `gc_vst` and `gc_deseq2` R objects in the end.
<i class="fas fa-lightbulb"></i> Tip Remember to take a look at how these files are formatted, before you import!
# Acknowledgements
Much of the data format explanations and exercises were obtained from the GitHub of [Eric C. Anderson](https://github.com/eriqande)
# Getting help
- Use `?function` to get function documentation
- Use `??bla` to search for a function
- Use `args(function)` to get the arguments to a function
- Go to the package CRAN page/webpage for vignettes
- [R Cookbook](http://www.cookbook-r.com/): General purpose reference.
- [Quick R](https://www.statmethods.net/): General purpose reference.
- [Stackoverflow](https://stackoverflow.com/): Online community to find solutions to your problems.
# Session info
```{r, fold.output=FALSE, fold.plot=FALSE}
sessionInfo()
```
__End of document__