Introduction:
In this lab we will learn:
- loading/storing data
- manipulating data
- saving data
- installing and using packages
PART 1: Loading data
There are essentially two ways in which you can easily load data
files into R. R has the ability to read in many different file types
(ex: .csv, .xlsx, etc). For the first portion of this course, we are
going to specifically be working with “.csv” files, later on we will
work with other file types common in bioinformatics.
FIRST WAY: files can be imported using the “Import Dataset” drop down
under the “Environment” tab (top right). For reading in “.csv” files,
you would select “From text (base)” then simply search your computer or
your cloud repository for the specific file you need. For “.csv” files,
you will get the option to re-name your file (highly recommended for
complicated file names - simple is best), you will also want to be sure
that heading is clicked “Yes” and that Separator is set to “Comma.” This
will give you a preview of what your file will look like, if it looks
good, go ahead and import!
SECOND WAY: files can be imported using code. You will have to find
and set an appropriate working directory. Running code tells R where to
look for certain files. The coding will give you the same opportunities
above to rename your file, tell R what separates cells, and whether or
not to keep column titles. We will practice this method below.
Finding and Setting a working directory
Regardless of whether you utilize the cloud or desktop version of
RStudio, you should create a folder on your desktop or in the cloud that
can be used to store and save files needed for this class, something
like “R Data”
When you try and import datasets into R, the program has a default
location that it looks for files. You can check what the default
location is by using the code below:
getwd()
[1] "/Users/alysonbarsalou/Downloads/R Data"
You’ll want to set your working directory to a location of your
choice, likely a folder you’ve created specifically for this purpose,
use the following code but plugging in your specific file path (HINT: it
can be really easy to copy and paste the output from the getwd() code
into the parentheses of setwd(), you will likely need to add an extra
step for the path):
setwd("/Users/alysonbarsalou/Downloads/R Data")
Here is what mine looks like when I switch from the default wd to one
where my data lives: > getwd() [1] “/Users/gordonober”
setwd(“/Users/gordonober/Desktop/R data”)
I had to add the “/Desktop/R data” to link to the R data folder on my
Desktop (if you right click on whatever folder you want to use, you can
typically find it’s path)
Loading data and data frames
Assuming your file is in CSV format (as most are), you can read
information into R by using the read.table()
command. The
general syntax will be
read.table('file_path/file_name.csv', sep=',', header=T)
,
below is code to read in the remission .csv files (which you will
download from Canvas and move to your working directory):
remission_data<-read.table('remission.csv',sep=',', header=T)
The remission_data
variable references an R data
frame; this is essentially the R version of an excel sheet. To see
the contents, we can just type the name and run a code chunk.
remission_data
Accessing data and statistical summaries
We can access the data in particular columns by using the
$
operator:
remission_data$LI
[1] 0.4 0.4 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8 0.8 0.9 1.0 1.0 1.0 1.1
[19] 1.1 1.2 1.3 1.4 1.6 1.7 1.9 1.9 1.9
Exercise 1:
*Below, create a code chunk and access the m
column of
the remission
_data` data frame.*
# Access the 'm' column from the 'remission_data' data frame
remission_data$m
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Once you have data loaded into R, you can easily manipulate it! This
might mean adding to it, converting values from a certain column,
removing certain values or rows.
Exercise 2: Applying some math!
What do you think the following command will do? (Answer below
the code chunk.)
remission_data$NewColumn <- log(remission_data$LI)
The code chunk above creates a new column titled “NewColumn” with the
natural logarithm values of the existing LI column. ****
Exercise 3: removing data
In some cases, you may want to exclude certain rows of data based on
one reason or another.
What do you think the following command will do? (Answer below
the code chunk.) BE SPECIFIC
remission_data <- remission_data[-c(2, 4, 6), ]
This command removes the 2nd, 4th, and 6th rows from the
remission_data data frame. • c(2, 4, 6) indicates the rows to remove. •
The negative sign (-) tells R to exclude the rows. • The empty space
after the comma (,) indicates that all the rest of the columns should be
retained. ****
NOTE: when you see [,] you can interpret this as [rows, columns]
Exercise 4: saving your new data
Exercises 2 and 3 had you add a column that manipulated an existing
one and had you remove rows you didn’t want from your original dataset.
Given this change, it can be useful to save your changes as a new .csv
file. The code below will save your data as a .csv file and the file can
be found in your working directory. The code below also allows you to
create your own new file name.
write.csv(remission_data, "new_remission_data.csv")
1. Load the data into R, give it a unique name, and visualize
it
bank_data<-read.table('BankWages.csv',sep=',', header=T)
bank_data
3. Remove rows from your data
bank_data <- bank_data[-c(30, 119, 204), ]
4. Save the data set as a new csv file.
write.csv(bank_data, "new_bank_data.csv")
NOTE: you do this in one code chunk or in many code chunks! As long
as you get there, that’s what matters.
Knitting to HTML and submitting
We’ve learned some very some useful commands for data analysis today.
We don’t want to forget them! Let’s hit the Preview
button
to create an HTML file where we can review these commands and their
output.
Once you get the markdown file into HTML format, please right click
on the page and save the file. You can upload this file to Canvas.
LS0tCnRpdGxlOiAiQklONTEwIFVOSVQgMTogTGFiIDEiCm5hbWU6IEFseXNvbiBCYXJzYWxvdSAKc3VidGl0bGU6IExvYWRpbmcgZGF0YSwgbWFuaXB1bGF0aW5nIGRhdGEsIGxvYWRpbmcgcGFja2FnZXMKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKIyMgSW50cm9kdWN0aW9uOgpJbiB0aGlzIGxhYiB3ZSB3aWxsIGxlYXJuOgoKKiBsb2FkaW5nL3N0b3JpbmcgZGF0YQoqIG1hbmlwdWxhdGluZyBkYXRhCiogc2F2aW5nIGRhdGEKKiBpbnN0YWxsaW5nIGFuZCB1c2luZyBwYWNrYWdlcwoKIyMgUEFSVCAxOiBMb2FkaW5nIGRhdGEKVGhlcmUgYXJlIGVzc2VudGlhbGx5IHR3byB3YXlzIGluIHdoaWNoIHlvdSBjYW4gZWFzaWx5IGxvYWQgZGF0YSBmaWxlcyBpbnRvIFIuIFIgaGFzIHRoZSBhYmlsaXR5IHRvIHJlYWQgaW4gbWFueSBkaWZmZXJlbnQgZmlsZSB0eXBlcyAoZXg6IC5jc3YsIC54bHN4LCBldGMpLiBGb3IgdGhlIGZpcnN0IHBvcnRpb24gb2YgdGhpcyBjb3Vyc2UsIHdlIGFyZSBnb2luZyB0byBzcGVjaWZpY2FsbHkgYmUgd29ya2luZyB3aXRoICIuY3N2IiBmaWxlcywgbGF0ZXIgb24gd2Ugd2lsbCB3b3JrIHdpdGggb3RoZXIgZmlsZSB0eXBlcyBjb21tb24gaW4gYmlvaW5mb3JtYXRpY3MuCgpGSVJTVCBXQVk6IGZpbGVzIGNhbiBiZSBpbXBvcnRlZCB1c2luZyB0aGUgIkltcG9ydCBEYXRhc2V0IiBkcm9wIGRvd24gdW5kZXIgdGhlICJFbnZpcm9ubWVudCIgdGFiICh0b3AgcmlnaHQpLiBGb3IgcmVhZGluZyBpbiAiLmNzdiIgZmlsZXMsIHlvdSB3b3VsZCBzZWxlY3QgIkZyb20gdGV4dCAoYmFzZSkiIHRoZW4gc2ltcGx5IHNlYXJjaCB5b3VyIGNvbXB1dGVyIG9yIHlvdXIgY2xvdWQgcmVwb3NpdG9yeSBmb3IgdGhlIHNwZWNpZmljIGZpbGUgeW91IG5lZWQuIEZvciAiLmNzdiIgZmlsZXMsIHlvdSB3aWxsIGdldCB0aGUgb3B0aW9uIHRvIHJlLW5hbWUgeW91ciBmaWxlIChoaWdobHkgcmVjb21tZW5kZWQgZm9yIGNvbXBsaWNhdGVkIGZpbGUgbmFtZXMgLSBzaW1wbGUgaXMgYmVzdCksIHlvdSB3aWxsIGFsc28gd2FudCB0byBiZSBzdXJlIHRoYXQgaGVhZGluZyBpcyBjbGlja2VkICJZZXMiIGFuZCB0aGF0IFNlcGFyYXRvciBpcyBzZXQgdG8gIkNvbW1hLiIgVGhpcyB3aWxsIGdpdmUgeW91IGEgcHJldmlldyBvZiB3aGF0IHlvdXIgZmlsZSB3aWxsIGxvb2sgbGlrZSwgaWYgaXQgbG9va3MgZ29vZCwgZ28gYWhlYWQgYW5kIGltcG9ydCEKClNFQ09ORCBXQVk6IGZpbGVzIGNhbiBiZSBpbXBvcnRlZCB1c2luZyBjb2RlLiBZb3Ugd2lsbCBoYXZlIHRvIGZpbmQgYW5kIHNldCBhbiBhcHByb3ByaWF0ZSB3b3JraW5nIGRpcmVjdG9yeS4gUnVubmluZyBjb2RlIHRlbGxzIFIgd2hlcmUgdG8gbG9vayBmb3IgY2VydGFpbiBmaWxlcy4gVGhlIGNvZGluZyB3aWxsIGdpdmUgeW91IHRoZSBzYW1lIG9wcG9ydHVuaXRpZXMgYWJvdmUgdG8gcmVuYW1lIHlvdXIgZmlsZSwgdGVsbCBSIHdoYXQgc2VwYXJhdGVzIGNlbGxzLCBhbmQgd2hldGhlciBvciBub3QgdG8ga2VlcCBjb2x1bW4gdGl0bGVzLiBXZSB3aWxsIHByYWN0aWNlIHRoaXMgbWV0aG9kIGJlbG93LgoKIyMgRmluZGluZyBhbmQgU2V0dGluZyBhIHdvcmtpbmcgZGlyZWN0b3J5ClJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB5b3UgdXRpbGl6ZSB0aGUgY2xvdWQgb3IgZGVza3RvcCB2ZXJzaW9uIG9mIFJTdHVkaW8sIHlvdSBzaG91bGQgY3JlYXRlIGEgZm9sZGVyIG9uIHlvdXIgZGVza3RvcCBvciBpbiB0aGUgY2xvdWQgdGhhdCBjYW4gYmUgdXNlZCB0byBzdG9yZSBhbmQgc2F2ZSBmaWxlcyBuZWVkZWQgZm9yIHRoaXMgY2xhc3MsIHNvbWV0aGluZyBsaWtlICJSIERhdGEiCgpXaGVuIHlvdSB0cnkgYW5kIGltcG9ydCBkYXRhc2V0cyBpbnRvIFIsIHRoZSBwcm9ncmFtIGhhcyBhIGRlZmF1bHQgbG9jYXRpb24gdGhhdCBpdCBsb29rcyBmb3IgZmlsZXMuIFlvdSBjYW4gY2hlY2sgd2hhdCB0aGUgZGVmYXVsdCBsb2NhdGlvbiBpcyBieSB1c2luZyB0aGUgY29kZSBiZWxvdzoKYGBge3J9CmdldHdkKCkKYGBgCgpZb3UnbGwgd2FudCB0byBzZXQgeW91ciB3b3JraW5nIGRpcmVjdG9yeSB0byBhIGxvY2F0aW9uIG9mIHlvdXIgY2hvaWNlLCBsaWtlbHkgYSBmb2xkZXIgeW91J3ZlIGNyZWF0ZWQgc3BlY2lmaWNhbGx5IGZvciB0aGlzIHB1cnBvc2UsIHVzZSB0aGUgZm9sbG93aW5nIGNvZGUgYnV0IHBsdWdnaW5nIGluIHlvdXIgc3BlY2lmaWMgZmlsZSBwYXRoIChISU5UOiBpdCBjYW4gYmUgcmVhbGx5IGVhc3kgdG8gY29weSBhbmQgcGFzdGUgdGhlIG91dHB1dCBmcm9tIHRoZSBnZXR3ZCgpIGNvZGUgaW50byB0aGUgcGFyZW50aGVzZXMgb2Ygc2V0d2QoKSwgeW91IHdpbGwgbGlrZWx5IG5lZWQgdG8gYWRkIGFuIGV4dHJhIHN0ZXAgZm9yIHRoZSBwYXRoKToKYGBge3J9CnNldHdkKCIvVXNlcnMvYWx5c29uYmFyc2Fsb3UvRG93bmxvYWRzL1IgRGF0YSIpCmBgYAoKSGVyZSBpcyB3aGF0IG1pbmUgbG9va3MgbGlrZSB3aGVuIEkgc3dpdGNoIGZyb20gdGhlIGRlZmF1bHQgd2QgdG8gb25lIHdoZXJlIG15IGRhdGEgbGl2ZXM6Cj4gZ2V0d2QoKQpbMV0gIi9Vc2Vycy9nb3Jkb25vYmVyIgoKPiBzZXR3ZCgiL1VzZXJzL2dvcmRvbm9iZXIvRGVza3RvcC9SIGRhdGEiKQoKSSBoYWQgdG8gYWRkIHRoZSAiL0Rlc2t0b3AvUiBkYXRhIiB0byBsaW5rIHRvIHRoZSBSIGRhdGEgZm9sZGVyIG9uIG15IERlc2t0b3AgKGlmIHlvdSByaWdodCBjbGljayBvbiB3aGF0ZXZlciBmb2xkZXIgeW91IHdhbnQgdG8gdXNlLCB5b3UgY2FuIHR5cGljYWxseSBmaW5kIGl0J3MgcGF0aCkKCgojIyBMb2FkaW5nIGRhdGEgYW5kIGRhdGEgZnJhbWVzCkFzc3VtaW5nIHlvdXIgZmlsZSBpcyBpbiBDU1YgZm9ybWF0IChhcyBtb3N0IGFyZSksIHlvdSBjYW4gcmVhZCBpbmZvcm1hdGlvbiBpbnRvIFIgYnkgdXNpbmcgdGhlIGByZWFkLnRhYmxlKClgIGNvbW1hbmQuICBUaGUgZ2VuZXJhbCBzeW50YXggd2lsbCBiZSBgcmVhZC50YWJsZSgnZmlsZV9wYXRoL2ZpbGVfbmFtZS5jc3YnLCBzZXA9JywnLCBoZWFkZXI9VClgLCBiZWxvdyBpcyBjb2RlIHRvIHJlYWQgaW4gdGhlIHJlbWlzc2lvbiAuY3N2IGZpbGVzICh3aGljaCB5b3Ugd2lsbCBkb3dubG9hZCBmcm9tIENhbnZhcyBhbmQgbW92ZSB0byB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5KToKYGBge3J9CnJlbWlzc2lvbl9kYXRhPC1yZWFkLnRhYmxlKCdyZW1pc3Npb24uY3N2JyxzZXA9JywnLCBoZWFkZXI9VCkKYGBgClRoZSBgcmVtaXNzaW9uX2RhdGFgIHZhcmlhYmxlIHJlZmVyZW5jZXMgYW4gUiAqZGF0YSBmcmFtZSo7IHRoaXMgaXMgZXNzZW50aWFsbHkgdGhlIFIgdmVyc2lvbiBvZiBhbiBleGNlbCBzaGVldC4gVG8gc2VlIHRoZSBjb250ZW50cywgd2UgY2FuIGp1c3QgdHlwZSB0aGUgbmFtZSBhbmQgcnVuIGEgY29kZSBjaHVuay4KYGBge3J9CnJlbWlzc2lvbl9kYXRhCmBgYAoKCiMjIEFjY2Vzc2luZyBkYXRhIGFuZCBzdGF0aXN0aWNhbCBzdW1tYXJpZXMKV2UgY2FuIGFjY2VzcyB0aGUgZGF0YSBpbiBwYXJ0aWN1bGFyIGNvbHVtbnMgYnkgdXNpbmcgdGhlIGAkYCBvcGVyYXRvcjoKYGBge3J9CnJlbWlzc2lvbl9kYXRhJExJCmBgYAoKIyMjIyBFeGVyY2lzZSAxOgoqQmVsb3csIGNyZWF0ZSBhIGNvZGUgY2h1bmsgYW5kIGFjY2VzcyB0aGUgYG1gIGNvbHVtbiBvZiB0aGUgYHJlbWlzc2lvbmBfZGF0YWAgZGF0YSBmcmFtZS4qCgoqKioqCmBgYHtyfQojIEFjY2VzcyB0aGUgJ20nIGNvbHVtbiBmcm9tIHRoZSAncmVtaXNzaW9uX2RhdGEnIGRhdGEgZnJhbWUKcmVtaXNzaW9uX2RhdGEkbQpgYGAKCk9uY2UgeW91IGhhdmUgZGF0YSBsb2FkZWQgaW50byBSLCB5b3UgY2FuIGVhc2lseSBtYW5pcHVsYXRlIGl0ISBUaGlzIG1pZ2h0IG1lYW4gYWRkaW5nIHRvIGl0LCBjb252ZXJ0aW5nIHZhbHVlcyBmcm9tIGEgY2VydGFpbiBjb2x1bW4sIHJlbW92aW5nIGNlcnRhaW4gdmFsdWVzIG9yIHJvd3MuIAoKIyMjIyBFeGVyY2lzZSAyOiBBcHBseWluZyBzb21lIG1hdGghCgoqV2hhdCBkbyB5b3UgdGhpbmsgdGhlIGZvbGxvd2luZyBjb21tYW5kIHdpbGwgZG8/IChBbnN3ZXIgYmVsb3cgdGhlIGNvZGUgY2h1bmsuKSoKYGBge3J9CnJlbWlzc2lvbl9kYXRhJE5ld0NvbHVtbiA8LSBsb2cocmVtaXNzaW9uX2RhdGEkTEkpCmBgYAoKKioqKgpUaGUgY29kZSBjaHVuayBhYm92ZSBjcmVhdGVzIGEgbmV3IGNvbHVtbiB0aXRsZWQgIk5ld0NvbHVtbiIgd2l0aCB0aGUgbmF0dXJhbCAKbG9nYXJpdGhtIHZhbHVlcyBvZiB0aGUgZXhpc3RpbmcgTEkgY29sdW1uLiAKKioqKgoKCiMjIyMgRXhlcmNpc2UgMzogcmVtb3ZpbmcgZGF0YQpJbiBzb21lIGNhc2VzLCB5b3UgbWF5IHdhbnQgdG8gZXhjbHVkZSBjZXJ0YWluIHJvd3Mgb2YgZGF0YSBiYXNlZCBvbiBvbmUgcmVhc29uIG9yIGFub3RoZXIuIAoKKldoYXQgZG8geW91IHRoaW5rIHRoZSBmb2xsb3dpbmcgY29tbWFuZCB3aWxsIGRvPyAoQW5zd2VyIGJlbG93IHRoZSBjb2RlIGNodW5rLikgQkUgU1BFQ0lGSUMqCmBgYHtyfQpyZW1pc3Npb25fZGF0YSA8LSByZW1pc3Npb25fZGF0YVstYygyLCA0LCA2KSwgXQpgYGAKCioqKioKVGhpcyBjb21tYW5kIHJlbW92ZXMgdGhlIDJuZCwgNHRoLCBhbmQgNnRoIHJvd3MgZnJvbSB0aGUgcmVtaXNzaW9uX2RhdGEgZGF0YSBmcmFtZS4K4oCiIGMoMiwgNCwgNikgaW5kaWNhdGVzIHRoZSByb3dzIHRvIHJlbW92ZS4K4oCiIFRoZSBuZWdhdGl2ZSBzaWduICgtKSB0ZWxscyBSIHRvIGV4Y2x1ZGUgdGhlIHJvd3MuCuKAoiBUaGUgZW1wdHkgc3BhY2UgYWZ0ZXIgdGhlIGNvbW1hICgsKSBpbmRpY2F0ZXMgdGhhdCBhbGwgdGhlIHJlc3Qgb2YgdGhlIGNvbHVtbnMgc2hvdWxkIGJlIHJldGFpbmVkLgoqKioqCgpOT1RFOiB3aGVuIHlvdSBzZWUgWyxdIHlvdSBjYW4gaW50ZXJwcmV0IHRoaXMgYXMgW3Jvd3MsIGNvbHVtbnNdCgojIyMjIEV4ZXJjaXNlIDQ6IHNhdmluZyB5b3VyIG5ldyBkYXRhCgpFeGVyY2lzZXMgMiBhbmQgMyBoYWQgeW91IGFkZCBhIGNvbHVtbiB0aGF0IG1hbmlwdWxhdGVkIGFuIGV4aXN0aW5nIG9uZSBhbmQgaGFkIHlvdSByZW1vdmUgcm93cyB5b3UgZGlkbid0IHdhbnQgZnJvbSB5b3VyIG9yaWdpbmFsIGRhdGFzZXQuIEdpdmVuIHRoaXMgY2hhbmdlLCBpdCBjYW4gYmUgdXNlZnVsIHRvIHNhdmUgeW91ciBjaGFuZ2VzIGFzIGEgbmV3IC5jc3YgZmlsZS4gVGhlIGNvZGUgYmVsb3cgd2lsbCBzYXZlIHlvdXIgZGF0YSBhcyBhIC5jc3YgZmlsZSBhbmQgdGhlIGZpbGUgY2FuIGJlIGZvdW5kIGluIHlvdXIgd29ya2luZyBkaXJlY3RvcnkuIFRoZSBjb2RlIGJlbG93IGFsc28gYWxsb3dzIHlvdSB0byBjcmVhdGUgeW91ciBvd24gbmV3IGZpbGUgbmFtZS4KCmBgYHtyfQp3cml0ZS5jc3YocmVtaXNzaW9uX2RhdGEsICJuZXdfcmVtaXNzaW9uX2RhdGEuY3N2IikKYGBgCgojIyMjIEV4ZXJjaXNlIDU6IFByYWN0aWNlIHRoaXMgd2l0aCBhbm90aGVyIGRhdGEgc2V0IQoKVXNpbmcgYSByZXBvc2l0b3J5IG9mIGRhdGEgc2V0IGZvciBSIChodHRwczovL3ZpbmNlbnRhcmVsYnVuZG9jay5naXRodWIuaW8vUmRhdGFzZXRzL2RhdGFzZXRzLmh0bWwpIGNob29zZSBhbnkgZGF0YSBzZXQgeW91IHdpc2ggYW5kIHBlcmZvcm0gdGhlIGZvbGxvd2luZyB0YXNrczoKCiMgMS4gTG9hZCB0aGUgZGF0YSBpbnRvIFIsIGdpdmUgaXQgYSB1bmlxdWUgbmFtZSwgYW5kIHZpc3VhbGl6ZSBpdAoKYGBge3J9CmJhbmtfZGF0YTwtcmVhZC50YWJsZSgnQmFua1dhZ2VzLmNzdicsc2VwPScsJywgaGVhZGVyPVQpCmJhbmtfZGF0YQpgYGAKCiMgMi4gQXBwbHkgbWF0aCBvZiB5b3VyIGNob2ljZSB0byBvbmUgb2YgdGhlIG51bWVyaWNhbCBjb2x1bW5zIChtYWtlIHN1cmUgeW91ciBkYXRhc2V0IGhhcyBvbmUgb2YgdGhlc2UhKSAtIHlvdSBjYW4gbG9nIHRyYW5zZm9ybSwgeW91IGNhbiBhZGQsIHN1YnRyYWN0LCBtdWx0aXBseSwgZGl2aWRlLCBldGMuIHZhbHVlcyAtIGNyZWF0ZSBhIG5ldyBjb2x1bW4gd2hlbiBkb2luZyB0aGlzCmBgYHtyfQojQWRkIDUgdG8gZWFjaCBudW1lcmljIHZhbHVlIGluIHRoZSBlZHVjYXRpb24gY29sdW1uIApiYW5rX2RhdGEkRWR1Y2F0aW9uQWRkNSA8LSBiYW5rX2RhdGEkZWR1Y2F0aW9uICsgNSAKYmFua19kYXRhCmBgYAoKIyAzLiBSZW1vdmUgcm93cyBmcm9tIHlvdXIgZGF0YQpgYGB7cn0KYmFua19kYXRhIDwtIGJhbmtfZGF0YVstYygzMCwgMTE5LCAyMDQpLCBdCmBgYAoKIyA0LiBTYXZlIHRoZSBkYXRhIHNldCBhcyBhIG5ldyBjc3YgZmlsZS4KYGBge3J9CndyaXRlLmNzdihiYW5rX2RhdGEsICJuZXdfYmFua19kYXRhLmNzdiIpCmBgYAoKTk9URTogeW91IGRvIHRoaXMgaW4gb25lIGNvZGUgY2h1bmsgb3IgaW4gbWFueSBjb2RlIGNodW5rcyEgQXMgbG9uZyBhcyB5b3UgZ2V0IHRoZXJlLCB0aGF0J3Mgd2hhdCBtYXR0ZXJzLgoKIyMjIyBLbml0dGluZyB0byBIVE1MIGFuZCBzdWJtaXR0aW5nCgpXZSd2ZSBsZWFybmVkIHNvbWUgdmVyeSBzb21lIHVzZWZ1bCBjb21tYW5kcyBmb3IgZGF0YSBhbmFseXNpcyB0b2RheS4gV2UgZG9uJ3Qgd2FudCB0byBmb3JnZXQgdGhlbSEgIExldCdzIGhpdCB0aGUgYFByZXZpZXdgIGJ1dHRvbiB0byBjcmVhdGUgYW4gSFRNTCBmaWxlIHdoZXJlIHdlIGNhbiByZXZpZXcgdGhlc2UgY29tbWFuZHMgYW5kIHRoZWlyIG91dHB1dC4KCk9uY2UgeW91IGdldCB0aGUgbWFya2Rvd24gZmlsZSBpbnRvIEhUTUwgZm9ybWF0LCBwbGVhc2UgcmlnaHQgY2xpY2sgb24gdGhlIHBhZ2UgYW5kIHNhdmUgdGhlIGZpbGUuIFlvdSBjYW4gdXBsb2FkIHRoaXMgZmlsZSB0byBDYW52YXMuCg==