Históricamente:
Entorno de desarrollo integrado (IDE) para R. Incluye:
Estructura de datos
La estructura de datos básica en R es el vector. Hay dos tipos básicos de vectores: vectores atómicos y listas.
Tienen tres propiedades comunes:
typeof()
(~ clase/modo)length()
(número de elementos)attributes()
(metadatos)Difieren en los tipos de sus elementos: todos los elementos de un vector atómico deben ser del mismo tipo, mientras que los elementos de una lista pueden tener diferentes tipos.
Homogeneous | Heterogeneous | |
---|---|---|
1d | Atomic vector | List |
2d | Matrix | Data frame |
nd | Array |
R no tiene elementos de 0 dimensiones (escalares). Los números o cadenas individuales son en realidad vectores de longitud uno.
Vectores atómicos
Tipos de vectores atómicos:
Los vectores se construyen usando c()
:
x <- 1
x1 <- c(1)
all.equal(x, x1)
## [1] TRUE
typeof(x)
## [1] "double"
class(x)
## [1] "numeric"
y <- "something"
class(y)
## [1] "character"
typeof(y)
## [1] "character"
w <- 1L
class(w)
## [1] "integer"
z <- TRUE
class(z)
## [1] "logical"
q <- factor(1)
class(q)
## [1] "factor"
Los vectores solo pueden contener entradas del mismo tipo. Los diferentes tipos serán obligados al tipo más flexible:
v <- c(10, 11, 12, 13)
class(v)
## [1] "numeric"
typeof(v)
## [1] "double"
is.integer(v)
## [1] FALSE
y <- c("Amazona", "Ara", "Eupsittula", "Myiopsitta")
class(y)
## [1] "character"
typeof(y)
## [1] "character"
is.integer(y)
## [1] FALSE
x <- c(1,2,3, "Myiopsitta")
x
## [1] "1" "2" "3" "Myiopsitta"
class(x)
## [1] "character"
typeof(x)
## [1] "character"
Los valores que faltan se especifican con NA, que es un vector lógico de longitud 1. NA siempre se fuerza a coincidir al tipo correcto de elemento si se usa dentro de c()
:
v <- c(10, 11, 12, 13, NA)
class(v)
## [1] "numeric"
v <- c(letters[1:3], NA)
class(v)
## [1] "character"
Listas
Puede contener objetos de diferentes clases y tamaños. Las listas se crean utilizando list()
:
l <- list(ID = letters[1:5], size = rnorm(6), observed = c(FALSE, TRUE, FALSE, FALSE, FALSE))
l
## $ID
## [1] "a" "b" "c" "d" "e"
##
## $size
## [1] 1.03711 1.76814 0.61309 -0.16713 1.12940 0.66704
##
## $observed
## [1] FALSE TRUE FALSE FALSE FALSE
class(l)
## [1] "list"
str(l)
## List of 3
## $ ID : chr [1:5] "a" "b" "c" "d" ...
## $ size : num [1:6] 1.037 1.768 0.613 -0.167 1.129 ...
## $ observed: logi [1:5] FALSE TRUE FALSE FALSE FALSE
… y dimensiones:
l <- list(ID = letters[1:5], size = rnorm(6), observed = c(FALSE, TRUE, FALSE, FALSE, FALSE), l)
str(l)
## List of 4
## $ ID : chr [1:5] "a" "b" "c" "d" ...
## $ size : num [1:6] 0.817 -0.924 0.84 0.441 0.505 ...
## $ observed: logi [1:5] FALSE TRUE FALSE FALSE FALSE
## $ :List of 3
## ..$ ID : chr [1:5] "a" "b" "c" "d" ...
## ..$ size : num [1:6] 1.037 1.768 0.613 -0.167 1.129 ...
## ..$ observed: logi [1:5] FALSE TRUE FALSE FALSE FALSE
l2 <- list(l, l)
str(l2)
## List of 2
## $ :List of 4
## ..$ ID : chr [1:5] "a" "b" "c" "d" ...
## ..$ size : num [1:6] 0.817 -0.924 0.84 0.441 0.505 ...
## ..$ observed: logi [1:5] FALSE TRUE FALSE FALSE FALSE
## ..$ :List of 3
## .. ..$ ID : chr [1:5] "a" "b" "c" "d" ...
## .. ..$ size : num [1:6] 1.037 1.768 0.613 -0.167 1.129 ...
## .. ..$ observed: logi [1:5] FALSE TRUE FALSE FALSE FALSE
## $ :List of 4
## ..$ ID : chr [1:5] "a" "b" "c" "d" ...
## ..$ size : num [1:6] 0.817 -0.924 0.84 0.441 0.505 ...
## ..$ observed: logi [1:5] FALSE TRUE FALSE FALSE FALSE
## ..$ :List of 3
## .. ..$ ID : chr [1:5] "a" "b" "c" "d" ...
## .. ..$ size : num [1:6] 1.037 1.768 0.613 -0.167 1.129 ...
## .. ..$ observed: logi [1:5] FALSE TRUE FALSE FALSE FALSE
Atributos
Los objetos pueden tener atributos. Los atributos permiten almacenar metadatos sobre el objeto. Los atributos son una especie de listas con nombre. Se puede acceder a los atributos individualmente con attr()
o todos a la vez (como una lista) con attributes()
:
y <- 1:10
mean(y)
## [1] 5.5
attr(y, "my_attribute") <- "This is not an apple"
attr(y, "my_attribute")
## [1] "This is not an apple"
str(y)
## int [1:10] 1 2 3 4 5 6 7 8 9 10
## - attr(*, "my_attribute")= chr "This is not an apple"
structure()
devuelve un nuevo objeto con atributos modificados:
y <- structure(1:10, my_attribute = "Arequipa 2019")
attributes(y)
## $my_attribute
## [1] "Arequipa 2019"
La mayoría de los atributos se pierden al modificar un vector:
attributes(y[1])
## NULL
Los únicos atributos que no se pierden son los tres más importantes:
w <- structure(c(a =1, b = 2), my_attribute = "Arequipa 2019")
attributes(w)
## $names
## [1] "a" "b"
##
## $my_attribute
## [1] "Arequipa 2019"
attributes(w[1])
## $names
## [1] "a"
class(w[1])
## [1] "numeric"
Nombres
Los vectores se pueden nombrar de tres maneras:
x <- c(a = 1, b = 2, c = 3)
x <- 1:3
; names(x) <- c("a", "b", "c")
O: x <- 1:3
; names(x)[[1]] <- c("a")
x <- setNames(1: 3, c ("a", "b", "c"))
y <- c(a = 1, 2, 3)
names(y)
## [1] "a" "" ""
v <- c(1, 2, 3)
names(v) <- c('a')
names(v)
## [1] "a" NA NA
z <- setNames(1:3, c("a", "b", "c"))
names(z)
## [1] "a" "b" "c"
Factores
Los atributos se utilizan para definir factores. Un factor es un vector que puede contener solo valores predefinidos y se utiliza para almacenar datos categóricos.
Los factores se construyen sobre vectores enteros utilizando dos atributos:
x <- factor(c("a", "b", "b", "a"))
x
## [1] a b b a
## Levels: a b
levels(x)
## [1] "a" "b"
str(x)
## Factor w/ 2 levels "a","b": 1 2 2 1
Los factores parecen vectores de caracteres, pero en realidad son enteros:
x <- factor(c("a", "b", "b", "a"))
c(x)
## [1] 1 2 2 1
Matrices
Todos los elementos son del mismo tipo:
m <- matrix(c(1, 2, 3, 11, 12, 13), nrow = 2)
dim(m)
## [1] 2 3
m
## [,1] [,2] [,3]
## [1,] 1 3 12
## [2,] 2 11 13
class(m)
## [1] "matrix"
m <- matrix(c(1, 2, 3, 11, 12,"13"), nrow = 2)
m
## [,1] [,2] [,3]
## [1,] "1" "3" "12"
## [2,] "2" "11" "13"
Se puede crear modificando el atributo de dimensión:
c <- 1:6
is.matrix(c)
## [1] FALSE
attributes(c)
## NULL
dim(c) <- c(3, 2)
c
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
is.matrix(c)
## [1] TRUE
attributes(c)
## $dim
## [1] 3 2
Arreglos (arrays)
Los arreglos (arrays) son matrices tridimensionales:
w <- array(
1:24,
dim = c(4, 3, 2),
dimnames = list(
c("one", "two", "three", "four"),
c("ein", "zwei", "drei"),
c("uno", "dos")
)
)
w
## , , uno
##
## ein zwei drei
## one 1 5 9
## two 2 6 10
## three 3 7 11
## four 4 8 12
##
## , , dos
##
## ein zwei drei
## one 13 17 21
## two 14 18 22
## three 15 19 23
## four 16 20 24
class(w)
## [1] "array"
dim(w)
## [1] 4 3 2
Los arreglos solo pueden contener elementos del mismo tipo:
w <- array(
c(1:12, letters[1:12]),
dim = c(4, 3, 2),
dimnames = list(
c("one", "two", "three", "four"),
c("ein", "zwei", "drei"),
c("uno", "dos")
)
)
w
## , , uno
##
## ein zwei drei
## one "1" "5" "9"
## two "2" "6" "10"
## three "3" "7" "11"
## four "4" "8" "12"
##
## , , dos
##
## ein zwei drei
## one "a" "e" "i"
## two "b" "f" "j"
## three "c" "g" "k"
## four "d" "h" "l"
Marcos de datos (data frames)
Son un tipo especial de listas. Pueden contener elementos de diferentes tipos:
m <- data.frame(ID = letters[1:5], size = rnorm(5), observed = c(FALSE, TRUE, FALSE, FALSE, FALSE))
dim(m)
## [1] 5 3
m
## ID size observed
## 1 a -0.83993 FALSE
## 2 b 3.13320 TRUE
## 3 c 0.30656 FALSE
## 4 d 1.28483 FALSE
## 5 e -1.47336 FALSE
class(m)
## [1] "data.frame"
is.data.frame(m)
## [1] TRUE
is.list(m)
## [1] TRUE
str(m)
## 'data.frame': 5 obs. of 3 variables:
## $ ID : Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
## $ size : num -0.84 3.133 0.307 1.285 -1.473
## $ observed: logi FALSE TRUE FALSE FALSE FALSE
Pero los vectores deben tener la misma longitud:
m <- data.frame(ID = letters[1:5], size = rnorm(6), observed = c(FALSE, TRUE, FALSE, FALSE, FALSE))
## Error in data.frame(ID = letters[1:5], size = rnorm(6), observed = c(FALSE, : arguments imply differing number of rows: 5, 6
Nota: data.frame()
convierte los vectores de caracteres en factores por defecto. Use stringsAsFactors = FALSE
para suprimir este comportamiento:
m <- data.frame(ID = letters[1:5], size = rnorm(6), observed = c(FALSE, TRUE, FALSE, FALSE, FALSE), stringsAsFactors = FALSE)
## Error in data.frame(ID = letters[1:5], size = rnorm(6), observed = c(FALSE, : arguments imply differing number of rows: 5, 6
str(m)
## 'data.frame': 5 obs. of 3 variables:
## $ ID : Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
## $ size : num -0.84 3.133 0.307 1.285 -1.473
## $ observed: logi FALSE TRUE FALSE FALSE FALSE
Elementos complejos se pueden agregar a un marco de datos usando I()
para tratar la lista como una unidad:
m <- data.frame(ID = letters[1:5], size = I(matrix(1:10, nrow = 5)), observed = c(FALSE, TRUE, FALSE, FALSE, FALSE))
m
## ID size.1 size.2 observed
## 1 a 1 6 FALSE
## 2 b 2 7 TRUE
## 3 c 3 8 FALSE
## 4 d 4 9 FALSE
## 5 e 5 10 FALSE
str(m)
## 'data.frame': 5 obs. of 3 variables:
## $ ID : Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
## $ size : 'AsIs' int [1:5, 1:2] 1 2 3 4 5 6 7 8 9 10
## $ observed: logi FALSE TRUE FALSE FALSE FALSE
Indexación
Los elementos dentro de los objetos pueden ser llamados por indexación. Para extraer un subconjunto de un vector, simplemente llame la posición del elemento utilizando corchetes:
x <- c(1, 3, 4, 10, 15, 20, 50, 1, 6)
x[1]
## [1] 1
x[2]
## [1] 3
x[2:3]
## [1] 3 4
x[c(1,3)]
## [1] 1 4
Los elementos se pueden quitar de la misma manera:
x[-1]
## [1] 3 4 10 15 20 50 1 6
x[-c(1,3)]
## [1] 3 10 15 20 50 1 6
Matrices y marcos de datos requieren 2 índices [fila, columna]
:
m <- matrix(c(1, 2, 3, 11, 12, 13), nrow = 2)
m[1, ]
## [1] 1 3 12
m[, 1]
## [1] 1 2
m[1, 1]
## [1] 1
m[-1, ]
## [1] 2 11 13
m[, -1]
## [,1] [,2]
## [1,] 3 12
## [2,] 11 13
m[-1, -1]
## [1] 11 13
df <- data.frame(family = c("Psittacidae", "Trochilidae",
"Psittacidae"),
genus = c("Amazona", "Phaethornis", "Ara"),
species = c("aestiva", "philippii", "ararauna"))
df
## family genus species
## 1 Psittacidae Amazona aestiva
## 2 Trochilidae Phaethornis philippii
## 3 Psittacidae Ara ararauna
df[1, ]
## family genus species
## 1 Psittacidae Amazona aestiva
df[, 1]
## [1] Psittacidae Trochilidae Psittacidae
## Levels: Psittacidae Trochilidae
df[1, 1]
## [1] Psittacidae
## Levels: Psittacidae Trochilidae
df[-1, ]
## family genus species
## 2 Trochilidae Phaethornis philippii
## 3 Psittacidae Ara ararauna
df[, -1]
## genus species
## 1 Amazona aestiva
## 2 Phaethornis philippii
## 3 Ara ararauna
df[-1, -1]
## genus species
## 2 Phaethornis philippii
## 3 Ara ararauna
df[,"family"]
## [1] Psittacidae Trochilidae Psittacidae
## Levels: Psittacidae Trochilidae
df[,c("family", "genus")]
## family genus
## 1 Psittacidae Amazona
## 2 Trochilidae Phaethornis
## 3 Psittacidae Ara
Las listas requieren 1 índice entre dobles corchetes [[índice]]
:
l <- list(ID = letters[1:5], size = rnorm(6), observed = c(FALSE, TRUE, FALSE, FALSE, FALSE))
l[[1]]
## [1] "a" "b" "c" "d" "e"
l[[3]]
## [1] FALSE TRUE FALSE FALSE FALSE
Los elementos dentro de las listas también pueden ser extraídos en la misma linea de código:
l[[1]][1:2]
## [1] "a" "b"
l[[3]][2]
## [1] TRUE
Explorar objectos
str(df)
## 'data.frame': 3 obs. of 3 variables:
## $ family : Factor w/ 2 levels "Psittacidae",..: 1 2 1
## $ genus : Factor w/ 3 levels "Amazona","Ara",..: 1 3 2
## $ species: Factor w/ 3 levels "aestiva","ararauna",..: 1 3 2
names(df)
## [1] "family" "genus" "species"
dim(df)
## [1] 3 3
nrow(df)
## [1] 3
ncol(df)
## [1] 3
head(df)
## family genus species
## 1 Psittacidae Amazona aestiva
## 2 Trochilidae Phaethornis philippii
## 3 Psittacidae Ara ararauna
tail(df)
## family genus species
## 1 Psittacidae Amazona aestiva
## 2 Trochilidae Phaethornis philippii
## 3 Psittacidae Ara ararauna
table(df$genus)
##
## Amazona Ara Phaethornis
## 1 1 1
typeof(df)
## [1] "list"
mode(df)
## [1] "list"
View(df)
Funciones básicas para la exploración/manipulación de datos (según Hadley Wickham):
# La primera que se debe aprender
?
str
# Operadores importantes
%in%, match
=, <-, <<-
$, [, [[, head, tail, subset
with
assign, get
# Comparar
all.equal, identical
!=, ==, >, >=, <, <=
is.na, complete.cases
is.finite
# Matematica basica
*, +, -, /, ^, %/%
abs, sign
acos, asin, atan, atan2
sin, cos, tan
ceiling, floor, round, trunc, signif
exp, log, log10, log2, sqrt
max, min, prod, sum
cummax, cummin, cumprod, cumsum, diff
pmax, pmin
range
mean, median, cor, sd, var
rle
# Funciones para hacer funciones
function
missing
on.exit
return, invisible
# Logicos
&, |, !, xor
all, any
intersect, union, setdiff, setequal
which
# Vectores y matrices
c, matrix
length, dim, ncol, nrow
cbind, rbind
names, colnames, rownames
t
diag
sweep
as.matrix, data.matrix
# Hacer vectores
c
rep, rep_len
seq, seq_len, seq_along
rev
sample
choose, factorial, combn
(is/as).(character/numeric/logical/...)
# Listas & data.frames
list, unlist
data.frame, as.data.frame
split
expand.grid
# Controlar procesos
if, &&, || (short circuiting)
for, while
next, break
switch
ifelse
# apply & relacionadas
lapply, sapply, vapply
apply
tapply
replicate
Todas las funciones son creadas por la función function()
y siguen la misma estructura:
* Modificado de Grolemund 2014
R viene con muchas funciones que se pueden usar para realizar tareas sofisticadas:
# built in functions
bi <- builtins()
length(bi)
## [1] 1346
sample(bi, 10)
## [1] "l10n_info" "qr.default" "rapply"
## [4] "rep.POSIXct" ".mergeImportMethods" "readRDS"
## [7] ".Internal" "all.equal.list" "is.na<-.default"
## [10] "intToBits"
Los operadores son funciones:
1 + 1
## [1] 2
'+'(1, 1)
## [1] 2
2 * 3
## [1] 6
'*'(2, 3)
## [1] 6
Operadores de R más comúnmente utilizados
Operadores aritméticos:
Operator | Description |
---|---|
+ | addition |
- | subtraction |
* | multiplication |
/ | division |
^ or ** | exponent |
x %% y | modulus (x mod y) |
x %/% y | integer division |
1 - 2
## [1] -1
1 + 2
## [1] 3
2 ^ 2
## [1] 4
2 ** 2
## [1] 4
5 %% 2
## [1] 1
5 %/% 2
## [1] 2
Operadores lógicos:
Operator | Description |
---|---|
< | less than |
<= | less than or equal to |
> | greater than |
>= | greater than or equal to |
== | exactly equal to |
!= | not equal to |
!x | Not x |
x | y | x OR y |
x & y | x AND y |
x %in% y | match |
1 < 2
## [1] TRUE
1 > 2
## [1] FALSE
1 <= 2
## [1] TRUE
1 == 2
## [1] FALSE
1 != 2
## [1] TRUE
1 > 2
## [1] FALSE
5 %in% 1:6
## [1] TRUE
5 %in% 1:4
## [1] FALSE
La mayoría de las funciones están vectorizadas:
1:6 * 1:6
* Modificado de Grolemund & Wickham 2017
## [1] 1 4 9 16 25 36
1:6 - 1:6
## [1] 0 0 0 0 0 0
R recicla vectores de longitud desigual:
1:6 * 1:5
* Modificado de Grolemund & Wickham 2017
## Warning in 1:6 * 1:5: longitud de objeto mayor no es múltiplo de la longitud de
## uno menor
## [1] 1 4 9 16 25 6
1:6 + 1:5
## Warning in 1:6 + 1:5: longitud de objeto mayor no es múltiplo de la longitud de
## uno menor
## [1] 2 4 6 8 10 7
Basado en la Guía de estilo de R de Google
Nombres de archivos
Los nombres de los archivos deben terminar en .R y, por supuesto, tener algún significado:
- BUENO: predict_ad_revenue.R
- MALO: foo.R
Nombres de objetos
Variables y funciones:
- BUENO: day_one: day_1, mean.day(),
- MALO: dayOne, day1, firstDay_of.month, mean <- function(x) sum(x), c <- 10
Syntaxis
Espaciado:
- BUENO:
a <- rnorm(n = 10, sd = 10, mean = 1)
tab.prior <- table(df[df$days.from.opt < 0, "campaign.id"])
total <- sum(x[, 1])
total <- sum(x[1, ])
if (debug)
mean(1:10)
- MALO:
a<-rnorm(n=10,sd=10,mean=1)
tab.prior <- table(df[df$days.from.opt<0, "campaign.id"]) # necesita espacio alrededor de '<'
tab.prior <- table(df[df$days.from.opt < 0,"campaign.id"]) # necesita espacio despues de la coma
tab.prior<- table(df[df$days.from.opt < 0, "campaign.id"]) # necesita espacio antes de '<-'
tab.prior<-table(df[df$days.from.opt < 0, "campaign.id"]) # necesita espacio alrededor de '<-'
total <- sum(x[,1]) # necesita espacio antes y despues de la coma
if(debug) # necesita espacio antes del parentesis
mean (1:10) # ) # espacio extra antes del parentesis
Paréntesis curvos:
- BUENO:
if (is.null(ylim)) {
ylim <- c(0, 0.06)
}
if (is.null(ylim))
ylim <- c(0, 0.06)
- MALO:
if (is.null(ylim)) ylim <- c(0, 0.06)
if (is.null(ylim)) {ylim <- c(0, 0.06)}
if (is.null(ylim)) {
ylim <- c(0, 0.06)
}
Asignación:
- BUENO:
x <- 5
- MALO:
x = 5
Pautas para comentar:
# Crear histograma de frecuencia de campañas
hist(df$pct.spent,
breaks = "scott", # metodo
main = "Histograma",
xlab = "la variable x",
ylab = "y la y")
Documentación de los paquetes
Manuales de referencia
Los manuales de referencia son colecciones de la documentación de todas las funciones en un paquete (solo 1 por paquete):
Documentación de las funciones
Todas las funciones (predeterminadas o de paquetes cargados) deben tener una documentación que siga un formato estándar:
?mean
help("mean")
Esta documentación también se puede mostrar en Rstudio presionando F1
cuando el cursor está en el nombre de la función
Si no recuerda el nombre de la función pruebe con apropos()
:
apropos("mean")
## [1] ".colMeans" ".rowMeans" "colMeans" "kmeans"
## [5] "mean" "mean.Date" "mean.default" "mean.difftime"
## [9] "mean.POSIXct" "mean.POSIXlt" "rowMeans" "weighted.mean"
Viñetas
Las viñetas son documentos ilustrativos o casos de estudio que detallan el uso de un paquete (son opcionales, pueden ser varios por paquete)
Las viñetas se pueden llamar directamente desde R:
vgn <- browseVignettes()
vignette()
También deben aparecer en la página de CRAN del paquete
Demostraciones
Los paquetes también pueden incluir demostraciones de código extendido (‘demos’). Para hacer un listado de las demostraciones en un paquete ejecute demo("nombre del paquete")
:
demo(package="stats")
demo("nlm")
vista de tareas de CRAN
Las vistas de tareas son compilaciones de paquetes relacionados con un tema específico:
[Vistas de tareas en CRAN] (https://cran.r-project.org/web/views/)
Para instalar automáticamente los paquetes en una vista, el paquete ctv
necesita ser instalado:
install.packages("ctv")
library("ctv")
Las vistas se pueden instalar a través de install.views()
o update.views()
(que primero evalúa cuáles de los paquetes ya están instalados y actualizados):
install.views("Econometrics")
#o
update.views("Econometrics")