This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

# creating a vector of numbers and then converting it to logical
   # and character
   numbers.vec <- c(-3,-2,-1,0,1,2,3)
numbers.vec
[1] -3 -2 -1  0  1  2  3
num2char <- as.character(numbers.vec)
num2char
[1] "-3" "-2" "-1" "0"  "1"  "2"  "3" 
num2logical <- as.logical(numbers.vec)
num2logical
[1]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
char.vec <- c("1","3","five","7")
char.vec
[1] "1"    "3"    "five" "7"   

Vector

Un vector es un arreglo de datos. En R, es el tipo básico de almacenaminto de datos. El vector puede ser numerico, caracter, y logico basado en sus elementos.

vector1 <- c(1,3,5,7,9)
vector1
[1] 1 3 5 7 9
# accessing second elements of "vector1"
vector1[2]
[1] 3
# accessing three elements starting from second element
vector1[2:4]
[1] 3 5 7

Factor

Un factor es otro tipo de dato importante en R, especialmente cuando se trata de variables categóricas. En un vector R, no hay límite en el número de elementos distintos, pero en las variables factoriales, sólo se requiere un número limitado de elementos distintos.

#creating factor variable with only one argument with factor()
factor1 <- factor(c(1,2,3,4,5,6,7,8,9))
factor1
[1] 1 2 3 4 5 6 7 8 9
Levels: 1 2 3 4 5 6 7 8 9

Data frame

Un marco de datos es una disposición rectangular de filas y columnas de vectores y/o factores, como una hoja de cálculo en MS Excel.

#creating vector of different variables and then creating data frame
var1 <- c(101,102,103,104,105)
var2 <- c(25,22,29,34,33)
var3 <- c("Non-Diabetic", "Diabetic", "Non-Diabetic", "Non-Diabetic", "Diabetic")
var4 <- factor(c("male","male","female","female","male"))
# now we will create data frame using two numeric vectors one
# character vector and one factor
diab.dat <- data.frame(var1,var2,var3,var4)
diab.dat

Determinar las clases de cada columna.

#class of each column before creating data frame
class(var1)
[1] "numeric"

Para acceder a columnas individuales de un dataframe use ($)

diab.dat$var1
[1] 101 102 103 104 105
diab.dat[["var1"]]
[1] 101 102 103 104 105
diab.dat[,1]
[1] 101 102 103 104 105

Matrices

Arreglo bidimensional de variables del mismo tipo.

# data frame to matrix conversion
mat.diab <- as.matrix(diab.dat)
mat.diab
     var1  var2 var3           var4    
[1,] "101" "25" "Non-Diabetic" "male"  
[2,] "102" "22" "Diabetic"     "male"  
[3,] "103" "29" "Non-Diabetic" "female"
[4,] "104" "34" "Non-Diabetic" "female"
[5,] "105" "33" "Diabetic"     "male"  
class(mat.diab)
[1] "matrix"

Para poder realizar operaciones matemáticas en matrices deben ser valores numericos.

# creating a matrix with numeric elements only
# To produce the same matrix over time we set a seed value
set.seed(12345)
num.mat <- matrix(rnorm(9),nrow=3,ncol=3)
num.mat
           [,1]       [,2]       [,3]
[1,]  0.5855288 -0.4534972  0.6300986
[2,]  0.7094660  0.6058875 -0.2761841
[3,] -0.1093033 -1.8179560 -0.2841597
# matrix multiplication
t(num.mat) %*% num.mat
          [,1]       [,2]       [,3]
[1,] 0.8581332 0.36302951 0.20405722
[2,] 0.3630295 3.87772320 0.06350551
[3,] 0.2040572 0.06350551 0.55404860

Arrays

Un arreglo es una entrada de datos de múltiples suscripciones que permite el almacenamiento de tramas de datos, matrices o vectores de diferentes tipos. Los marcos y matrices de datos son de dos dimensiones solamente, pero un arreglo puede ser de cualquier número de dimensiones.

mat.array=array(dim=c(2,2,3))
# To produce the same results over time we set a seed value
set.seed(12345)
mat.array[,,1]<-rnorm(4)
mat.array[,,2]<-rnorm(4)
mat.array[,,3]<-rnorm(4)
mat.array
, , 1

          [,1]       [,2]
[1,] 0.5855288 -0.1093033
[2,] 0.7094660 -0.4534972

, , 2

           [,1]       [,2]
[1,]  0.6058875  0.6300986
[2,] -1.8179560 -0.2761841

, , 3

           [,1]       [,2]
[1,] -0.2841597 -0.1162478
[2,] -0.9193220  1.8173120

list

Es un objeto que puede almacenar otros objetos de cualquier tipo.

var1 <- c(101,102,103,104,105)
var2 <- c(25,22,29,34,33)
var3 <- c("Non-Diabetic", "Diabetic", "Non-Diabetic", "Non-Diabetic",
"Diabetic")
var4 <- factor(c("male","male","female","female","male"))
diab.dat <- data.frame(var1,var2,var3,var4)
mat.array=array(dim=c(2,2,3))
set.seed(12345)
mat.array[,,1]<-rnorm(4)
mat.array[,,2]<-rnorm(4)
mat.array[,,3]<-rnorm(4)
# creating list
obj.list <- list(elem1=var1, elem2=var2, elem3=var3, elem4=var4, elem5=diab.dat, elem6=mat.array)
obj.list
$elem1
[1] 101 102 103 104 105

$elem2
[1] 25 22 29 34 33

$elem3
[1] "Non-Diabetic" "Diabetic"     "Non-Diabetic" "Non-Diabetic"
[5] "Diabetic"    

$elem4
[1] male   male   female female male  
Levels: female male

$elem5

$elem6
, , 1

          [,1]       [,2]
[1,] 0.5855288 -0.1093033
[2,] 0.7094660 -0.4534972

, , 2

           [,1]       [,2]
[1,]  0.6058875  0.6300986
[2,] -1.8179560 -0.2761841

, , 3

           [,1]       [,2]
[1,] -0.2841597 -0.1162478
[2,] -0.9193220  1.8173120

Acceso a elementos de la lista.

obj.list[[1]]
[1] 101 102 103 104 105

Missing values

missing_dat <- data.frame(v1=c(1,NA,0,1),v2=c("M","F",NA,"M"))
missing_dat
is.na(missing_dat$v1)
[1] FALSE  TRUE FALSE FALSE
is.na(missing_dat$v2)
[1] FALSE FALSE  TRUE FALSE
any(is.na(missing_dat))
[1] TRUE

Basic Data Manipulation

Acquiring data

Formatos comunes: Comma separated values (.csv), Text file with Tab delimited, MS Excel file (.xls or .xlsx) , R data object (.RData)

# Before running the following command we need to set the data
# location using setwd(). For example setwd("d:/chap2").
anscombe <- read.csv("datos.csv",skip=2)
no fue posible abrir el archivo 'datos.csv': No such file or directoryError in file(file, "rt") : no se puede abrir la conexión

Importar archivo csv separado por semicolon (“;”)

Importar archivo csv separado por tab (“”)

Excel file

Calling xlsx library

library(xlsx) # importing xlsxanscombe.xlsx ans_xlsx <- read.xlsx2(“datos.xlsx”,sheetIndex=1)

Rdata

loading robjects.RData file

load(“robjects.RData”)

Date processing

# Second January 1970 is showing number of elapsed day is 1.
as.Date("1970-01-02")
[1] "1970-01-02"
as.numeric(as.Date("1970-01-02"))
[1] 1
# creating date object specifying format of date
as.Date("Jan-01-1970",format="%b-%d-%Y")
[1] NA
# loading lubridate package
library(lubridate)

Attaching package: ‘lubridate’

The following object is masked from ‘package:base’:

    date
# creating date object using mdy() function
mdy("Jan-01-1970")
[1] "1970-01-01"
# Creating date object using based R functionality
   date <- as.POSIXct("23-07-2013",format = "%d-%m-%Y", tz = "UTC")
# extracting month from the date object
   as.numeric(format(date, "%m"))
[1] 7
# accessing system date and time
   current_time <- now()
   current_time
[1] "2019-09-07 03:14:42 -03"
# changing time zone to "GMT"
   current_time_gmt <- with_tz(current_time,"GMT")
   current_time_gmt
[1] "2019-09-07 06:14:42 GMT"
# rounding the date to nearest day
   round_date(current_time_gmt,"day")
[1] "2019-09-07 GMT"

Character manipulation

Uso de librería “stringr” str_c(): This function is used to concatenate a vector of characters with a default separator as a space. str_length(): This returns the number of characters in a character string str_dup(): This is used to duplicate the characters within a string. str_trim(): This is used to remove the leading and trailing whitespaces. str_pad(): This is used to pad a string with extra whitespaces on the left, right, or both sides.

library(stringr)

Subconjuntos

# creating a 10 element vector
num10 <- c(3,2,5,3,9,6,7,9,2,3)
# accessing fifth element
num10[5]
# checking whether there is any value of num10 object greater
# than 6
num10>6
# keeping only values greater than 6
num10[num10>6]
# use of negative subscript removes first element "3"
num10[-1]

para objetos bidimensionales

# creating a data frame with 2 variables
data_2variable <- data.frame(x1=c(2,3,4,5,6),x2=c(5,6,7,8,1))
# accessing only first row
data_2variable[1,]
# accessing only first column
   data_2variable[,1]
[1] 2 3 4 5 6
# accessing first row and first column
   data_2variable[1,1]
[1] 2

seleccion de matrices

list_obj<- list(dat=data_2variable,vec.obj=c(1,2,3))
list_obj
$dat

$vec.obj
[1] 1 2 3
$vec.obj
# accessing second element of the list_obj objects
   list_obj[[2]]
# accessing dataset from the list object 
list_obj$dat
LS0tCnRpdGxlOiAiUiBEYXRhIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpgYGB7cn0KCmBgYAoKCmBgYHtyfQojIGNyZWF0aW5nIGEgdmVjdG9yIG9mIG51bWJlcnMgYW5kIHRoZW4gY29udmVydGluZyBpdCB0byBsb2dpY2FsCiAgICMgYW5kIGNoYXJhY3RlcgogICBudW1iZXJzLnZlYyA8LSBjKC0zLC0yLC0xLDAsMSwyLDMpCm51bWJlcnMudmVjCmBgYAoKYGBge3J9Cm51bTJjaGFyIDwtIGFzLmNoYXJhY3RlcihudW1iZXJzLnZlYykKbnVtMmNoYXIKYGBgCgpgYGB7cn0KbnVtMmxvZ2ljYWwgPC0gYXMubG9naWNhbChudW1iZXJzLnZlYykKbnVtMmxvZ2ljYWwKYGBgCgpgYGB7cn0KY2hhci52ZWMgPC0gYygiMSIsIjMiLCJmaXZlIiwiNyIpCmNoYXIudmVjCmBgYAojI1ZlY3RvcgpVbiB2ZWN0b3IgZXMgdW4gYXJyZWdsbyBkZSBkYXRvcy4gRW4gUiwgZXMgZWwgdGlwbyBiw6FzaWNvIGRlIGFsbWFjZW5hbWludG8gZGUgZGF0b3MuIEVsIHZlY3RvciBwdWVkZSBzZXIgbnVtZXJpY28sIGNhcmFjdGVyLCB5IGxvZ2ljbyBiYXNhZG8gZW4gc3VzIGVsZW1lbnRvcy4gCmBgYHtyfQp2ZWN0b3IxIDwtIGMoMSwzLDUsNyw5KQp2ZWN0b3IxCmBgYAoKYGBge3J9CiMgYWNjZXNzaW5nIHNlY29uZCBlbGVtZW50cyBvZiAidmVjdG9yMSIKdmVjdG9yMVsyXQpgYGAKCmBgYHtyfQojIGFjY2Vzc2luZyB0aHJlZSBlbGVtZW50cyBzdGFydGluZyBmcm9tIHNlY29uZCBlbGVtZW50CnZlY3RvcjFbMjo0XQpgYGAKIyNGYWN0b3IKVW4gZmFjdG9yIGVzIG90cm8gdGlwbyBkZSBkYXRvIGltcG9ydGFudGUgZW4gUiwgZXNwZWNpYWxtZW50ZSBjdWFuZG8gc2UgdHJhdGEgZGUgdmFyaWFibGVzIGNhdGVnw7NyaWNhcy4gRW4gdW4gdmVjdG9yIFIsIG5vIGhheSBsw61taXRlIGVuIGVsIG7Dum1lcm8gZGUgZWxlbWVudG9zIGRpc3RpbnRvcywgcGVybyBlbiBsYXMgdmFyaWFibGVzIGZhY3RvcmlhbGVzLCBzw7NsbyBzZSByZXF1aWVyZSB1biBuw7ptZXJvIGxpbWl0YWRvIGRlIGVsZW1lbnRvcyBkaXN0aW50b3MuCmBgYHtyfQojY3JlYXRpbmcgZmFjdG9yIHZhcmlhYmxlIHdpdGggb25seSBvbmUgYXJndW1lbnQgd2l0aCBmYWN0b3IoKQpmYWN0b3IxIDwtIGZhY3RvcihjKDEsMiwzLDQsNSw2LDcsOCw5KSkKZmFjdG9yMQpgYGAKIyNEYXRhIGZyYW1lClVuIG1hcmNvIGRlIGRhdG9zIGVzIHVuYSBkaXNwb3NpY2nDs24gcmVjdGFuZ3VsYXIgZGUgZmlsYXMgeSBjb2x1bW5hcyBkZSB2ZWN0b3JlcyB5L28gZmFjdG9yZXMsIGNvbW8gdW5hIGhvamEgZGUgY8OhbGN1bG8gZW4gTVMgRXhjZWwuIApgYGB7cn0KI2NyZWF0aW5nIHZlY3RvciBvZiBkaWZmZXJlbnQgdmFyaWFibGVzIGFuZCB0aGVuIGNyZWF0aW5nIGRhdGEgZnJhbWUKdmFyMSA8LSBjKDEwMSwxMDIsMTAzLDEwNCwxMDUpCnZhcjIgPC0gYygyNSwyMiwyOSwzNCwzMykKdmFyMyA8LSBjKCJOb24tRGlhYmV0aWMiLCAiRGlhYmV0aWMiLCAiTm9uLURpYWJldGljIiwgIk5vbi1EaWFiZXRpYyIsICJEaWFiZXRpYyIpCnZhcjQgPC0gZmFjdG9yKGMoIm1hbGUiLCJtYWxlIiwiZmVtYWxlIiwiZmVtYWxlIiwibWFsZSIpKQojIG5vdyB3ZSB3aWxsIGNyZWF0ZSBkYXRhIGZyYW1lIHVzaW5nIHR3byBudW1lcmljIHZlY3RvcnMgb25lCiMgY2hhcmFjdGVyIHZlY3RvciBhbmQgb25lIGZhY3RvcgpkaWFiLmRhdCA8LSBkYXRhLmZyYW1lKHZhcjEsdmFyMix2YXIzLHZhcjQpCmRpYWIuZGF0CmBgYApEZXRlcm1pbmFyIGxhcyBjbGFzZXMgZGUgY2FkYSBjb2x1bW5hLgpgYGB7cn0KI2NsYXNzIG9mIGVhY2ggY29sdW1uIGJlZm9yZSBjcmVhdGluZyBkYXRhIGZyYW1lCmNsYXNzKHZhcjEpCmBgYApQYXJhIGFjY2VkZXIgYSBjb2x1bW5hcyBpbmRpdmlkdWFsZXMgZGUgdW4gZGF0YWZyYW1lIHVzZSAoJCkKYGBge3J9CmRpYWIuZGF0JHZhcjEKZGlhYi5kYXRbWyJ2YXIxIl1dCmRpYWIuZGF0WywxXQpgYGAKIyNNYXRyaWNlcwpBcnJlZ2xvIGJpZGltZW5zaW9uYWwgZGUgdmFyaWFibGVzIGRlbCBtaXNtbyB0aXBvLgpgYGB7cn0KIyBkYXRhIGZyYW1lIHRvIG1hdHJpeCBjb252ZXJzaW9uCm1hdC5kaWFiIDwtIGFzLm1hdHJpeChkaWFiLmRhdCkKbWF0LmRpYWIKYGBgCgpgYGB7cn0KY2xhc3MobWF0LmRpYWIpCmBgYApQYXJhIHBvZGVyIHJlYWxpemFyIG9wZXJhY2lvbmVzIG1hdGVtw6F0aWNhcyBlbiBtYXRyaWNlcyBkZWJlbiBzZXIgdmFsb3JlcyBudW1lcmljb3MuCmBgYHtyfQojIGNyZWF0aW5nIGEgbWF0cml4IHdpdGggbnVtZXJpYyBlbGVtZW50cyBvbmx5CiMgVG8gcHJvZHVjZSB0aGUgc2FtZSBtYXRyaXggb3ZlciB0aW1lIHdlIHNldCBhIHNlZWQgdmFsdWUKc2V0LnNlZWQoMTIzNDUpCm51bS5tYXQgPC0gbWF0cml4KHJub3JtKDkpLG5yb3c9MyxuY29sPTMpCm51bS5tYXQKYGBgCgpgYGB7cn0KIyBtYXRyaXggbXVsdGlwbGljYXRpb24KdChudW0ubWF0KSAlKiUgbnVtLm1hdApgYGAKCiMjQXJyYXlzClVuIGFycmVnbG8gZXMgdW5hIGVudHJhZGEgZGUgZGF0b3MgZGUgbcO6bHRpcGxlcyBzdXNjcmlwY2lvbmVzIHF1ZSBwZXJtaXRlIGVsIGFsbWFjZW5hbWllbnRvIGRlIHRyYW1hcyBkZSBkYXRvcywgbWF0cmljZXMgbyB2ZWN0b3JlcyBkZSBkaWZlcmVudGVzIHRpcG9zLiBMb3MgbWFyY29zIHkgbWF0cmljZXMgZGUgZGF0b3Mgc29uIGRlIGRvcyBkaW1lbnNpb25lcyBzb2xhbWVudGUsIHBlcm8gdW4gYXJyZWdsbyBwdWVkZSBzZXIgZGUgY3VhbHF1aWVyIG7Dum1lcm8gZGUgZGltZW5zaW9uZXMuCmBgYHtyfQptYXQuYXJyYXk9YXJyYXkoZGltPWMoMiwyLDMpKQojIFRvIHByb2R1Y2UgdGhlIHNhbWUgcmVzdWx0cyBvdmVyIHRpbWUgd2Ugc2V0IGEgc2VlZCB2YWx1ZQpzZXQuc2VlZCgxMjM0NSkKbWF0LmFycmF5WywsMV08LXJub3JtKDQpCm1hdC5hcnJheVssLDJdPC1ybm9ybSg0KQptYXQuYXJyYXlbLCwzXTwtcm5vcm0oNCkKbWF0LmFycmF5CmBgYAojI2xpc3QKRXMgdW4gb2JqZXRvIHF1ZSBwdWVkZSBhbG1hY2VuYXIgb3Ryb3Mgb2JqZXRvcyBkZSBjdWFscXVpZXIgdGlwby4KYGBge3J9CnZhcjEgPC0gYygxMDEsMTAyLDEwMywxMDQsMTA1KQp2YXIyIDwtIGMoMjUsMjIsMjksMzQsMzMpCnZhcjMgPC0gYygiTm9uLURpYWJldGljIiwgIkRpYWJldGljIiwgIk5vbi1EaWFiZXRpYyIsICJOb24tRGlhYmV0aWMiLAoiRGlhYmV0aWMiKQp2YXI0IDwtIGZhY3RvcihjKCJtYWxlIiwibWFsZSIsImZlbWFsZSIsImZlbWFsZSIsIm1hbGUiKSkKZGlhYi5kYXQgPC0gZGF0YS5mcmFtZSh2YXIxLHZhcjIsdmFyMyx2YXI0KQptYXQuYXJyYXk9YXJyYXkoZGltPWMoMiwyLDMpKQpzZXQuc2VlZCgxMjM0NSkKbWF0LmFycmF5WywsMV08LXJub3JtKDQpCm1hdC5hcnJheVssLDJdPC1ybm9ybSg0KQptYXQuYXJyYXlbLCwzXTwtcm5vcm0oNCkKIyBjcmVhdGluZyBsaXN0Cm9iai5saXN0IDwtIGxpc3QoZWxlbTE9dmFyMSwgZWxlbTI9dmFyMiwgZWxlbTM9dmFyMywgZWxlbTQ9dmFyNCwgZWxlbTU9ZGlhYi5kYXQsIGVsZW02PW1hdC5hcnJheSkKb2JqLmxpc3QKYGBgCkFjY2VzbyBhIGVsZW1lbnRvcyBkZSBsYSBsaXN0YS4KYGBge3J9Cm9iai5saXN0W1sxXV0KYGBgCiMjTWlzc2luZyB2YWx1ZXMKYGBge3J9Cm1pc3NpbmdfZGF0IDwtIGRhdGEuZnJhbWUodjE9YygxLE5BLDAsMSksdjI9YygiTSIsIkYiLE5BLCJNIikpCm1pc3NpbmdfZGF0CmBgYAoKYGBge3J9CmlzLm5hKG1pc3NpbmdfZGF0JHYxKQppcy5uYShtaXNzaW5nX2RhdCR2MikKYW55KGlzLm5hKG1pc3NpbmdfZGF0KSkKYGBgCiNCYXNpYyBEYXRhIE1hbmlwdWxhdGlvbgojI0FjcXVpcmluZyBkYXRhCkZvcm1hdG9zIGNvbXVuZXM6CkNvbW1hIHNlcGFyYXRlZCB2YWx1ZXMgKCouY3N2KSwgVGV4dCBmaWxlIHdpdGggVGFiIGRlbGltaXRlZCwgTVMgRXhjZWwgZmlsZSAoKi54bHMgb3IgKi54bHN4KSAsIFIgZGF0YSBvYmplY3QgKCouUkRhdGEpCmBgYHtyfQojIEJlZm9yZSBydW5uaW5nIHRoZSBmb2xsb3dpbmcgY29tbWFuZCB3ZSBuZWVkIHRvIHNldCB0aGUgZGF0YQojIGxvY2F0aW9uIHVzaW5nIHNldHdkKCkuIEZvciBleGFtcGxlIHNldHdkKCJkOi9jaGFwMiIpLgphbnNjb21iZSA8LSByZWFkLmNzdigiZGF0b3MuY3N2Iixza2lwPTIpCiNza2lwPTIgaW5kaWNhIHF1ZSBzZSBzYWx0ZSAyIGZpbGFzIHkgcG9yIHRhbnRvIGxvcyBkYXRvcyBzZSBpbmljaWFuIGVuIGxhIHRlcmNlcmEgZmlsYS4KYGBgCgpgYGB7cn0KIyBpbXBvcnQgY3N2IGZpbGUgdGhhdCBjb250YWlucyBib3RoIG51bWVyaWMgYW5kIGNoYXJhY3RlciB2YXJpYWJsZQojIGZpcnN0bHkgdXNpbmcgZGVmYXVsdCBhbmQgdGhlbiB1c2luZyBzdHJpbmdzQXNGQWN0b3JzPUZBTFNFCmlyaXNfYSA8LSByZWFkLmNzdigiaXJpcy5jc3YiKQpzdHIoaXJpc19hKQpgYGAKCmBgYHtyfQojIE5vdyB1c2luZyBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFCmlyaXNfYiA8LSByZWFkLmNzdigiaXJpcy5jc3YiLHN0cmluZ3NBc0ZhY3RvcnM9RikKYGBgCkltcG9ydGFyIGFyY2hpdm8gY3N2IHNlcGFyYWRvIHBvciBzZW1pY29sb24gKCI7IikKYGBge3J9CmlyaXNfc2VtaWNvbG9uIDwtCnJlYWQuY3N2KCJkYXRvcy5jc3YiLHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0Usc2VwPSI7IikKc3RyKGlyaXNfc2VtaWNvbG9uKQpgYGAKSW1wb3J0YXIgYXJjaGl2byBjc3Ygc2VwYXJhZG8gcG9yIHRhYiAoIlx0IikKYGBge3J9CmFuc2NvbWJlX3RhYiA8LSByZWFkLmNzdigiYW5zY29tYmUudHh0IixzZXA9Ilx0IikKYW5zY29tYmVfdGFiXzIgPC0gcmVhZC50YWJsZSgiYW5zY29tYmUudHh0IixoZWFkZXI9VFJVRSkKYGBgCiMjRXhjZWwgZmlsZQojIENhbGxpbmcgeGxzeCBsaWJyYXJ5CmxpYnJhcnkoeGxzeCkKIyBpbXBvcnRpbmcgeGxzeGFuc2NvbWJlLnhsc3gKYW5zX3hsc3ggPC0gcmVhZC54bHN4MigiZGF0b3MueGxzeCIsc2hlZXRJbmRleD0xKQpgYGB7cn0KIyBDYWxsaW5nIHhsc3ggbGlicmFyeQpsaWJyYXJ5KHhsc3gpCiMgaW1wb3J0aW5nIHhsc3hhbnNjb21iZS54bHN4CmFuc194bHN4IDwtIHJlYWQueGxzeDIoImRhdG9zLnhsc3giLHNoZWV0SW5kZXg9MSkKYGBgCiMjUmRhdGEKIyBsb2FkaW5nIHJvYmplY3RzLlJEYXRhIGZpbGUKbG9hZCgicm9iamVjdHMuUkRhdGEiKQpgYGB7cn0KIyBsb2FkaW5nIHJvYmplY3RzLlJEYXRhIGZpbGUKbG9hZCgicm9iamVjdHMuUkRhdGEiKQpgYGAKIyNEYXRlIHByb2Nlc3NpbmcKYGBge3J9CiMgY3JlYXRpbmcgZGF0ZSBvYmplY3QgdXNpbmcgYnVpbHQgaW4gYXMuRGF0ZSgpIGZ1bmN0aW9uCmFzLkRhdGUoIjE5NzAtMDEtMDEiKQpgYGAKCmBgYHtyfQojIGxvb2tpbmcgYXQgdGhlIGludGVybmFsIHZhbHVlIG9mIGRhdGUgb2JqZWN0CiAgIGFzLm51bWVyaWMoYXMuRGF0ZSgiMTk3MC0wMS0wMSIpKQpgYGAKCmBgYHtyfQojIFNlY29uZCBKYW51YXJ5IDE5NzAgaXMgc2hvd2luZyBudW1iZXIgb2YgZWxhcHNlZCBkYXkgaXMgMS4KYXMuRGF0ZSgiMTk3MC0wMS0wMiIpCmFzLm51bWVyaWMoYXMuRGF0ZSgiMTk3MC0wMS0wMiIpKQpgYGAKCmBgYHtyfQojIGNyZWF0aW5nIGRhdGUgb2JqZWN0IHNwZWNpZnlpbmcgZm9ybWF0IG9mIGRhdGUKYXMuRGF0ZSgiSmFuLTAxLTE5NzAiLGZvcm1hdD0iJWItJWQtJVkiKQpgYGAKCmBgYHtyfQojIGxvYWRpbmcgbHVicmlkYXRlIHBhY2thZ2UKbGlicmFyeShsdWJyaWRhdGUpCiMgY3JlYXRpbmcgZGF0ZSBvYmplY3QgdXNpbmcgbWR5KCkgZnVuY3Rpb24KbWR5KCJKYW4tMDEtMTk3MCIpCmBgYApgYGB7cn0KIyBDcmVhdGluZyBkYXRlIG9iamVjdCB1c2luZyBiYXNlZCBSIGZ1bmN0aW9uYWxpdHkKICAgZGF0ZSA8LSBhcy5QT1NJWGN0KCIyMy0wNy0yMDEzIixmb3JtYXQgPSAiJWQtJW0tJVkiLCB0eiA9ICJVVEMiKQojIGV4dHJhY3RpbmcgbW9udGggZnJvbSB0aGUgZGF0ZSBvYmplY3QKICAgYXMubnVtZXJpYyhmb3JtYXQoZGF0ZSwgIiVtIikpCmBgYAoKYGBge3J9CiMgYWNjZXNzaW5nIHN5c3RlbSBkYXRlIGFuZCB0aW1lCiAgIGN1cnJlbnRfdGltZSA8LSBub3coKQogICBjdXJyZW50X3RpbWUKYGBgCgpgYGB7cn0KIyBjaGFuZ2luZyB0aW1lIHpvbmUgdG8gIkdNVCIKICAgY3VycmVudF90aW1lX2dtdCA8LSB3aXRoX3R6KGN1cnJlbnRfdGltZSwiR01UIikKICAgY3VycmVudF90aW1lX2dtdApgYGAKCmBgYHtyfQojIHJvdW5kaW5nIHRoZSBkYXRlIHRvIG5lYXJlc3QgZGF5CiAgIHJvdW5kX2RhdGUoY3VycmVudF90aW1lX2dtdCwiZGF5IikKYGBgCiNDaGFyYWN0ZXIgbWFuaXB1bGF0aW9uClVzbyBkZSBsaWJyZXLDrWEgInN0cmluZ3IiCnN0cl9jKCk6IFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBjb25jYXRlbmF0ZSBhIHZlY3RvciBvZiBjaGFyYWN0ZXJzIHdpdGggYSBkZWZhdWx0IHNlcGFyYXRvciBhcyBhIHNwYWNlLiAKc3RyX2xlbmd0aCgpOiBUaGlzIHJldHVybnMgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIGEgY2hhcmFjdGVyIHN0cmluZwpzdHJfZHVwKCk6IFRoaXMgaXMgdXNlZCB0byBkdXBsaWNhdGUgdGhlIGNoYXJhY3RlcnMgd2l0aGluIGEgc3RyaW5nLgpzdHJfdHJpbSgpOiBUaGlzIGlzIHVzZWQgdG8gcmVtb3ZlIHRoZSBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlcy4Kc3RyX3BhZCgpOiBUaGlzIGlzIHVzZWQgdG8gcGFkIGEgc3RyaW5nIHdpdGggZXh0cmEgd2hpdGVzcGFjZXMgb24gdGhlIGxlZnQsIHJpZ2h0LCBvciBib3RoIHNpZGVzLgpgYGB7cn0KbGlicmFyeShzdHJpbmdyKQoKYGBgCiNTdWJjb25qdW50b3MKYGBge3J9CiMgY3JlYXRpbmcgYSAxMCBlbGVtZW50IHZlY3RvcgoKYGBgCgpgYGB7cn0KbnVtMTAgPC0gYygzLDIsNSwzLDksNiw3LDksMiwzKQojIGFjY2Vzc2luZyBmaWZ0aCBlbGVtZW50Cm51bTEwWzVdCmBgYAoKYGBge3J9CiMgY2hlY2tpbmcgd2hldGhlciB0aGVyZSBpcyBhbnkgdmFsdWUgb2YgbnVtMTAgb2JqZWN0IGdyZWF0ZXIKIyB0aGFuIDYKbnVtMTA+NgpgYGAKCmBgYHtyfQojIGtlZXBpbmcgb25seSB2YWx1ZXMgZ3JlYXRlciB0aGFuIDYKbnVtMTBbbnVtMTA+Nl0KYGBgCgpgYGB7cn0KIyB1c2Ugb2YgbmVnYXRpdmUgc3Vic2NyaXB0IHJlbW92ZXMgZmlyc3QgZWxlbWVudCAiMyIKbnVtMTBbLTFdCmBgYAojI3BhcmEgb2JqZXRvcyBiaWRpbWVuc2lvbmFsZXMKYGBge3J9CiMgY3JlYXRpbmcgYSBkYXRhIGZyYW1lIHdpdGggMiB2YXJpYWJsZXMKZGF0YV8ydmFyaWFibGUgPC0gZGF0YS5mcmFtZSh4MT1jKDIsMyw0LDUsNikseDI9Yyg1LDYsNyw4LDEpKQojIGFjY2Vzc2luZyBvbmx5IGZpcnN0IHJvdwpkYXRhXzJ2YXJpYWJsZVsxLF0KYGBgCgpgYGB7cn0KIyBhY2Nlc3Npbmcgb25seSBmaXJzdCBjb2x1bW4KICAgZGF0YV8ydmFyaWFibGVbLDFdCmBgYAoKYGBge3J9CiMgYWNjZXNzaW5nIGZpcnN0IHJvdyBhbmQgZmlyc3QgY29sdW1uCiAgIGRhdGFfMnZhcmlhYmxlWzEsMV0KYGBgCiMjc2VsZWNjaW9uIGRlIG1hdHJpY2VzCmBgYHtyfQpsaXN0X29iajwtIGxpc3QoZGF0PWRhdGFfMnZhcmlhYmxlLHZlYy5vYmo9YygxLDIsMykpCmxpc3Rfb2JqCmBgYApgYGB7cn0KJHZlYy5vYmoKYGBgCgpgYGB7cn0KIyBhY2Nlc3Npbmcgc2Vjb25kIGVsZW1lbnQgb2YgdGhlIGxpc3Rfb2JqIG9iamVjdHMKICAgbGlzdF9vYmpbWzJdXQpgYGAKCmBgYHtyfQojIGFjY2Vzc2luZyBkYXRhc2V0IGZyb20gdGhlIGxpc3Qgb2JqZWN0IApsaXN0X29iaiRkYXQKYGBgCgo=