1 Opercaciones matemáticas

1.1 Suma

4 + 8
## [1] 12

1.2 Multiplicación y división

2 * 5 / 6
## [1] 1.666667
(2 * 5) / 6
## [1] 1.666667
2 * (5 / 6)
## [1] 1.666667

1.3 Suma y división

2 + 5 / 6
## [1] 2.833333
(2 + 5) / 6
## [1] 1.166667
2 + (5 / 6)
## [1] 2.833333

1.4 Potenciación

3 ^ 2
## [1] 9
3 ** 2
## [1] 9

1.5 Potenciación y suma

4 + 5 ^ 2
## [1] 29
4 + 5 ** 2
## [1] 29
(4 + 5) ^ 2
## [1] 81
(4 + 5) ** 2
## [1] 81

1.6 Redondear número

10 / 3
## [1] 3.333333
round(10 / 3, 2)
## [1] 3.33
round(10 / 3, 1)
## [1] 3.3
round(10 / 3, 0)
## [1] 3

1.7 Raíz cuadrada

sqrt(2)
## [1] 1.414214
sqrt(9)
## [1] 3
sqrt(81)
## [1] 9

1.8 Exponencial de un número

exp(0)
## [1] 1
exp(1)
## [1] 2.718282
exp(7)
## [1] 1096.633

1.9 Número pi

pi
## [1] 3.141593

2 Asignación de nombres

suma <- 4 + 8

suma
## [1] 12
suma1 <- 5 + 9

suma1
## [1] 14
producto <- 4 * 3

producto
## [1] 12
potencia <- suma ** producto

potencia
## [1] 8.9161e+12

8’916.100’000.000

3 Tipos de objetos

3.1 Enteros

entero <- 7

class(entero)
## [1] "numeric"

3.2 Carácteres

genero0 <- "masculino"

class(genero0)
## [1] "character"

3.3 Factores

genero1 <- factor("femenino", levels = c("femenino","masculino"))

genero2 <- factor("masculino", levels = c("femenino","masculino"))

genero1
## [1] femenino
## Levels: femenino masculino
genero2
## [1] masculino
## Levels: femenino masculino

3.4 Lógica o booleana

verdadero <- TRUE

falso <- FALSE

class(verdadero)
## [1] "logical"
genero1 == "masculino"
## [1] FALSE

4 Vectores

4.1 “c”: concatenar

vector <- c(15, 23 ,45, 67, 78, 90)

4.2 “seq”: secuencia

seq(from = 3, to = 6)
## [1] 3 4 5 6
seq(from = 9, by = -1, length.out = 3)
## [1] 9 8 7
3:6
## [1] 3 4 5 6

4.3 Letras

LETTERS
##  [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S"
## [20] "T" "U" "V" "W" "X" "Y" "Z"
letters
##  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
## [20] "t" "u" "v" "w" "x" "y" "z"

4.3.1 Indexación

vector[2]
## [1] 23
vector[3:5]
## [1] 45 67 78
vector[c(1,3,4,5)]
## [1] 15 45 67 78
LETTERS[3:6]
## [1] "C" "D" "E" "F"
letters[-(2:25)]
## [1] "a" "z"

4.4 Funciones y expresiones

4.4.1 Suma

sum(vector)
## [1] 318

4.4.2 Longitud

length(vector)
## [1] 6

4.4.3 Exponencial

exp(1/vector)
## [1] 1.068939 1.044437 1.022471 1.015037 1.012903 1.011173

4.4.4 Redondeo

round(exp(1/vector), 3)
## [1] 1.069 1.044 1.022 1.015 1.013 1.011

4.5 Instalación y carga de librerías

4.5.1 Visualización de todos los paquetes instalados

library()

4.5.2 Instalación

install.packages("dplyr", dependencies = TRUE)

4.5.3 Carga

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

4.5.4 Localización

.libPaths()
## [1] "/home/rstudio-user/R/x86_64-pc-linux-gnu-library/4.0"
## [2] "/opt/R/4.0.3/lib/R/library"

4.5.5 Visualización de todos los paquetes cargados

search()
##  [1] ".GlobalEnv"        "package:dplyr"     "package:stats"    
##  [4] "package:graphics"  "package:grDevices" "package:utils"    
##  [7] "package:datasets"  "package:methods"   "Autoloads"        
## [10] "package:base"

4.6 Marcos de datos (Data frame)

paquetes <- library(help = "datasets")

head(paquetes$info2[[2]])
## NULL

QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ

Para saber en que directorio de trabajo esta guardando y buscando los archivos su sesión de R la instrucción es la siguiente:

getwd()
## [1] "/cloud/project"

el siguiente comando despliega una lista de todos los archivos que tiene actualmente en su directorio de trabajo.

ls()
##  [1] "entero"    "falso"     "genero0"   "genero1"   "genero2"   "paquetes" 
##  [7] "potencia"  "producto"  "suma"      "suma1"     "vector"    "verdadero"

Si asigna un valor númerico a un objeto x en este caso, y luego usa el comando ls() la lista de elementos se actualizará.

x <- 9
ls()
##  [1] "entero"    "falso"     "genero0"   "genero1"   "genero2"   "paquetes" 
##  [7] "potencia"  "producto"  "suma"      "suma1"     "vector"    "verdadero"
## [13] "x"

Liste todos los archivos en el directorio de trabajo usando “list.files()” o dir().

list.files()  
## [1] "mytest2.R"     "mytest3.R"     "project.Rproj" "r basico.Rmd" 
## [5] "r-basico.html" "r-basico.Rmd"  "rsconnect"     "testdir"
dir()
## [1] "mytest2.R"     "mytest3.R"     "project.Rproj" "r basico.Rmd" 
## [5] "r-basico.html" "r-basico.Rmd"  "rsconnect"     "testdir"

A medida que avanzamos con la leccion, puede ir consultando la pagina de ayuda de las funciones. Eche un vistazo a la pagina de ayuda para list.files con el comando “?list.files”. La seccion de See Also muestra funciones complementarias.

?list.files

Use la funcion args() con el nombre de una funcion list.files para conocer que argumentos necesita o require la funcion.

args(list.files)
## function (path = ".", pattern = NULL, all.files = FALSE, full.names = FALSE, 
##     recursive = FALSE, ignore.case = FALSE, include.dirs = FALSE, 
##     no.. = FALSE) 
## NULL

Ahora, asigne el valor del directorio de trabajo actual a una nueva variable llamada “old.dir”. Al final de la leccion, usaremos old.dir para regresar al directorio original de trabajo.

old.dir <- getwd()

Use dir.create() para crear un directorio llamado “testdir” en el directorio de trabajo actual.

dir.create("testdir")
## Warning in dir.create("testdir"): 'testdir' already exists

A partir de ahora, usaremos este nuevo directorio de trabajo, y finalmente lo borraremos. Por ello, establece como directorio de trabajo el directorio “testdir” con el comando setwd().

setwd("testdir")

Cree un archivo en el directorio de trabajo llamado “mytest.R” usando la funcion file.create(). Este archivo sera el unico en el directorio creado. Revise esto listando todos los archivos del directorio de trabajo. Finalmente, revisa si “mytest.R” existe en el directorio de trabajo usando la funcion file exists().

file.create("mytest.R")
## [1] TRUE
list.files()
## [1] "mytest.R"      "mytest2.R"     "mytest3.R"     "project.Rproj"
## [5] "r basico.Rmd"  "r-basico.html" "r-basico.Rmd"  "rsconnect"    
## [9] "testdir"
file.exists("mytest.R")
## [1] TRUE

Este tipo de funciones son excesivas para el uso interactivo. Pero, si esta ejecutando un programa que recorre una serie de archivos y hace algunos procesamiento en cada uno, tendra que comprobar que cada uno existe antes intentar procesarlo.

Observa informacion sobre el archivo “mytest.R” usando file.info(). Puede usar el operador $ — por ejemplo, file.info(“mytest.R”)$mode — para acceder a items especificos.

file.info("mytest.R")
##          size isdir mode               mtime               ctime
## mytest.R    0 FALSE  664 2020-11-19 12:23:04 2020-11-19 12:23:04
##                        atime   uid   gid        uname       grname
## mytest.R 2020-11-19 12:23:04 10001 10001 rstudio-user rstudio-user

Cambie el nombre del archivo “mytest.R” a “mytest2.R” con file.rename().

file.rename("mytest.R", "mytest2.R")
## [1] TRUE

Su sistema operativo proporciona herramientas mas sencillas para este tipo de tareas, pero tener la capacidad de manipular archivos mediante programacion es util. Puede elimine mytest.R usando file.remove(‘mytest.R’). Tenga en cuenta que esto no funcionara con mytest.R ya que el archivo no existe. Usted ya lo ha cambiado.

Haga una copia de “mytest2.R” a un nuevo archivo llamado “mytest3.R” usando file.copy().

file.copy("mytest2.R", "mytest3.R")
## [1] FALSE

Ahora tiene dos archivos en el directorio de trabajo. Ello no parece muy interesante, pero piense que estuviera trabajando con decenas, cientos o millones de archivos? En este caso, sera absolutamente necesario acceder de forma automatica a los archivos.

Utilice el camino relativo (relative path) al archivo “mytest3.R” usando file.path(). Puede usar file.path para construir caminos a archivos y directorios que sean independientes al sistema operativo. Utilice ‘folder1’y ’folder2’ como argumentos en file.path para hacer que el camino sea independiente a la plataforma.

file.path("mytest3.R")
## [1] "mytest3.R"
ruta <- file.path("folder1", "folder2")

Observe la documentacion de dir.create con “?dir.create”. Note el argumento ‘recursive’ que se utiliza para craear directorios anidados (nested). En este caso ‘recursive’ debe ser TRUE. Ahora cree un directorio en el directorio de trabajo actual llamado “testdir2” y un subdirectorio llamado “testdir3”, todo en un solo comando usando dir.create() y file.path().

?dir.create dir.create(file.path(“testdir2”, “testdir3”), recursive = TRUE)

Para borrar un directorio tiene que utilizar el argumento recursive = TRUE con la funcion unlink(). Si no se usa recursive = TRUE, R no sabra que desea borrar el directorio con todo su contenido. Borre el directorio “testdir2” usando unlink().

unlink(“testdir2”, recursive = TRUE)

Vuelva al directorio de trabajo original usando setwd(). Recuerde que este directorio se almaceno en la variable old.dir.

setwd(old.dir)

Borre el directorio ‘testdir’ con todo su contenido

unlink(“testdir”, recursive = TRUE)

4.7 Principales objetos en R

La información que manipulamos en R se estructura en forma de objetos. Para trabajar con R resulta importante conocer los principales tipos de objetos y sus propiedades básicas. En general, cada tipo de objeto viene definido por una serie de atributos. Las funciones genéricas (como por ejemplo summary o plot) reconocen estos atributos y llevan a cabo distintos tipos de acciones en función del tipo de objeto. Aquí nos vamos a centrar solo en los objetos más utilizados: vectores, matrices, listas, data frames y factores.

4.7.1 Vectores

Algunos comandos para generar vectores

Para encadenar dos vectores podemos usar el comando c(). Los escalares son, a todos los efectos, vectores de longitud 1:

x <- c(2, 4, 6)
y <- c(3, 7)
c(x, y)
## [1] 2 4 6 3 7

Para generar sucesiones o vectores de valores repetidos podemos usar los siguientes comandos:

a <- 100:500
seq(2, 10, 2)
## [1]  2  4  6  8 10
seq(2, 10, 3)
## [1] 2 5 8
rep(c(1, 2, 3), 4)
##  [1] 1 2 3 1 2 3 1 2 3 1 2 3
rep(1:5,5)
##  [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5

4.8 Reciclaje

Es muy importante para operar con vectores tener en cuenta la regla del reciclaje: si usamos vectores que no alcanzan la dimensión adecuada para ciertas operaciones, R automáticamente recicla el vector (repite los valores) hasta llegar a la dimensión requerida.

100 + c(1, 2, 3)
## [1] 101 102 103
c(1, 2) + c(7, 8, 9)
## Warning in c(1, 2) + c(7, 8, 9): longer object length is not a multiple of
## shorter object length
## [1]  8 10 10

Por una parte, esta propiedad es peligrosa ya que podemos cometer errores sin darnos cuenta. La parte positiva es que muchas veces permite ahorrar código. En el segundo de los ejemplos anteriores vemos que si la dimensión del vector no es un divisor de la dimensión adecuada, recibimos un mensaje de aviso (pero se sigue aplicando el reciclaje y la operación se lleva a cabo).

4.9 Valores especiales

Las expresiones NA, NaN, Inf, NULL están reservadas para los valores especiales Not Available, Not a Number, Infinity y Null, respectivamente. Para entender cómo opera R con estos valores, observa los ejemplos siguientes:

x <- c(NA, NaN, Inf, 0, 3, NULL)
1/x
## [1]        NA       NaN 0.0000000       Inf 0.3333333
x - x
## [1]  NA NaN NaN   0   0
1/x - (x - x)
## [1]        NA       NaN       NaN       Inf 0.3333333

El valor Null corresponde a vacío y es ignorado. Puede ser útil sin embargo si queremos crear un objeto que luego vamos a ir completando poco a poco.

4.10 Selección de las coordenadas de un vector

Se usan corchetes para generar subvectores formados por algunas de las coordenadas de un vector:

x <- (1:5)^2
x
## [1]  1  4  9 16 25
x <- (1:500)**2
x
##   [1]      1      4      9     16     25     36     49     64     81    100
##  [11]    121    144    169    196    225    256    289    324    361    400
##  [21]    441    484    529    576    625    676    729    784    841    900
##  [31]    961   1024   1089   1156   1225   1296   1369   1444   1521   1600
##  [41]   1681   1764   1849   1936   2025   2116   2209   2304   2401   2500
##  [51]   2601   2704   2809   2916   3025   3136   3249   3364   3481   3600
##  [61]   3721   3844   3969   4096   4225   4356   4489   4624   4761   4900
##  [71]   5041   5184   5329   5476   5625   5776   5929   6084   6241   6400
##  [81]   6561   6724   6889   7056   7225   7396   7569   7744   7921   8100
##  [91]   8281   8464   8649   8836   9025   9216   9409   9604   9801  10000
## [101]  10201  10404  10609  10816  11025  11236  11449  11664  11881  12100
## [111]  12321  12544  12769  12996  13225  13456  13689  13924  14161  14400
## [121]  14641  14884  15129  15376  15625  15876  16129  16384  16641  16900
## [131]  17161  17424  17689  17956  18225  18496  18769  19044  19321  19600
## [141]  19881  20164  20449  20736  21025  21316  21609  21904  22201  22500
## [151]  22801  23104  23409  23716  24025  24336  24649  24964  25281  25600
## [161]  25921  26244  26569  26896  27225  27556  27889  28224  28561  28900
## [171]  29241  29584  29929  30276  30625  30976  31329  31684  32041  32400
## [181]  32761  33124  33489  33856  34225  34596  34969  35344  35721  36100
## [191]  36481  36864  37249  37636  38025  38416  38809  39204  39601  40000
## [201]  40401  40804  41209  41616  42025  42436  42849  43264  43681  44100
## [211]  44521  44944  45369  45796  46225  46656  47089  47524  47961  48400
## [221]  48841  49284  49729  50176  50625  51076  51529  51984  52441  52900
## [231]  53361  53824  54289  54756  55225  55696  56169  56644  57121  57600
## [241]  58081  58564  59049  59536  60025  60516  61009  61504  62001  62500
## [251]  63001  63504  64009  64516  65025  65536  66049  66564  67081  67600
## [261]  68121  68644  69169  69696  70225  70756  71289  71824  72361  72900
## [271]  73441  73984  74529  75076  75625  76176  76729  77284  77841  78400
## [281]  78961  79524  80089  80656  81225  81796  82369  82944  83521  84100
## [291]  84681  85264  85849  86436  87025  87616  88209  88804  89401  90000
## [301]  90601  91204  91809  92416  93025  93636  94249  94864  95481  96100
## [311]  96721  97344  97969  98596  99225  99856 100489 101124 101761 102400
## [321] 103041 103684 104329 104976 105625 106276 106929 107584 108241 108900
## [331] 109561 110224 110889 111556 112225 112896 113569 114244 114921 115600
## [341] 116281 116964 117649 118336 119025 119716 120409 121104 121801 122500
## [351] 123201 123904 124609 125316 126025 126736 127449 128164 128881 129600
## [361] 130321 131044 131769 132496 133225 133956 134689 135424 136161 136900
## [371] 137641 138384 139129 139876 140625 141376 142129 142884 143641 144400
## [381] 145161 145924 146689 147456 148225 148996 149769 150544 151321 152100
## [391] 152881 153664 154449 155236 156025 156816 157609 158404 159201 160000
## [401] 160801 161604 162409 163216 164025 164836 165649 166464 167281 168100
## [411] 168921 169744 170569 171396 172225 173056 173889 174724 175561 176400
## [421] 177241 178084 178929 179776 180625 181476 182329 183184 184041 184900
## [431] 185761 186624 187489 188356 189225 190096 190969 191844 192721 193600
## [441] 194481 195364 196249 197136 198025 198916 199809 200704 201601 202500
## [451] 203401 204304 205209 206116 207025 207936 208849 209764 210681 211600
## [461] 212521 213444 214369 215296 216225 217156 218089 219024 219961 220900
## [471] 221841 222784 223729 224676 225625 226576 227529 228484 229441 230400
## [481] 231361 232324 233289 234256 235225 236196 237169 238144 239121 240100
## [491] 241081 242064 243049 244036 245025 246016 247009 248004 249001 250000
x[496]
## [1] 246016
x[c(2, 496)]
## [1]      4 246016

Pueden utilizarse valores negativos dentro del corchete para eliminar coordenadas:

x[-c(200:500)]
##   [1]     1     4     9    16    25    36    49    64    81   100   121   144
##  [13]   169   196   225   256   289   324   361   400   441   484   529   576
##  [25]   625   676   729   784   841   900   961  1024  1089  1156  1225  1296
##  [37]  1369  1444  1521  1600  1681  1764  1849  1936  2025  2116  2209  2304
##  [49]  2401  2500  2601  2704  2809  2916  3025  3136  3249  3364  3481  3600
##  [61]  3721  3844  3969  4096  4225  4356  4489  4624  4761  4900  5041  5184
##  [73]  5329  5476  5625  5776  5929  6084  6241  6400  6561  6724  6889  7056
##  [85]  7225  7396  7569  7744  7921  8100  8281  8464  8649  8836  9025  9216
##  [97]  9409  9604  9801 10000 10201 10404 10609 10816 11025 11236 11449 11664
## [109] 11881 12100 12321 12544 12769 12996 13225 13456 13689 13924 14161 14400
## [121] 14641 14884 15129 15376 15625 15876 16129 16384 16641 16900 17161 17424
## [133] 17689 17956 18225 18496 18769 19044 19321 19600 19881 20164 20449 20736
## [145] 21025 21316 21609 21904 22201 22500 22801 23104 23409 23716 24025 24336
## [157] 24649 24964 25281 25600 25921 26244 26569 26896 27225 27556 27889 28224
## [169] 28561 28900 29241 29584 29929 30276 30625 30976 31329 31684 32041 32400
## [181] 32761 33124 33489 33856 34225 34596 34969 35344 35721 36100 36481 36864
## [193] 37249 37636 38025 38416 38809 39204 39601

También se pueden usar operaciones lógicas para seleccionar las coordenadas que cumplen cierta condición. El comando which se usa para saber los índices de las coordenadas que cumplen la condición:

x <- (10:100)^2
x
##  [1]   100   121   144   169   196   225   256   289   324   361   400   441
## [13]   484   529   576   625   676   729   784   841   900   961  1024  1089
## [25]  1156  1225  1296  1369  1444  1521  1600  1681  1764  1849  1936  2025
## [37]  2116  2209  2304  2401  2500  2601  2704  2809  2916  3025  3136  3249
## [49]  3364  3481  3600  3721  3844  3969  4096  4225  4356  4489  4624  4761
## [61]  4900  5041  5184  5329  5476  5625  5776  5929  6084  6241  6400  6561
## [73]  6724  6889  7056  7225  7396  7569  7744  7921  8100  8281  8464  8649
## [85]  8836  9025  9216  9409  9604  9801 10000
x[x > 5000]
##  [1]  5041  5184  5329  5476  5625  5776  5929  6084  6241  6400  6561  6724
## [13]  6889  7056  7225  7396  7569  7744  7921  8100  8281  8464  8649  8836
## [25]  9025  9216  9409  9604  9801 10000
which(x > 5000)
##  [1] 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
## [26] 87 88 89 90 91

4.11 Matrices

Las matrices son también vectores pero con dos atributos adicionales: número de filas y número de columnas. Sin embargo, los vectores no son matrices con una fila o con una columna. Para crear una matriz:

matrix(1:3, nrow = 2, ncol = 3, byrow = FALSE)
##      [,1] [,2] [,3]
## [1,]    1    3    2
## [2,]    2    1    3

El primer argumento es un vector que incluye los elementos de la matriz y los otros dos corresponden al número de filas y columnas. Los elementos se van colocando por columnas. Observa cómo se ha aplicado la regla del reciclaje en el ejemplo anterior.

Veamos qué ocurre al sumar un vector y una matriz:

matrix(1:9, 3, 3)
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
c(1, 2, 3) + matrix(1:9, 3, 3)
##      [,1] [,2] [,3]
## [1,]    2    5    8
## [2,]    4    7   10
## [3,]    6    9   12

Tal vez es conveniente explicar paso a paso el resultado de la operación anterior:

La matriz es considerada como un vector. El vector que resulta de apilar sus columnas una sobre otra.
Los vectores se suman, aplicando la regla de reciclaje ya que las dimensiones no coinciden.
El vector resultante de la suma hereda los atributos (número de filas y columnas) de la matriz.

En el ejemplo siguiente, la matriz es de nuevo considerada como un vector. Se seleccionan todas las entradas de la matriz mayores que seis y se devuelven en forma de vector. Los índices correspondientes se refieren también a la matriz considerada como vector.

x <- matrix(5:8, 3, 4)
x
##      [,1] [,2] [,3] [,4]
## [1,]    5    8    7    6
## [2,]    6    5    8    7
## [3,]    7    6    5    8
x[x > 6]
## [1] 7 8 7 8 7 8
which(x < 6)
## [1] 1 5 9

4.12 Selección de entradas de una matriz

Usando corchetes es posible extraer submatrices. Dentro del corchete, separadas por una coma, se indican las filas y columnas que queremos extraer (o eliminar si usamos números negativos). Si no se pone nada antes o después de la coma se extraen todas las filas o columnas, respectivamente:

x
##      [,1] [,2] [,3] [,4]
## [1,]    5    8    7    6
## [2,]    6    5    8    7
## [3,]    7    6    5    8
x[1,]
## [1] 5 8 7 6
x[2,]
## [1] 6 5 8 7
x[3,]
## [1] 7 6 5 8
x[,1]
## [1] 5 6 7
x[,2]
## [1] 8 5 6
x[,3]
## [1] 7 8 5
x[,4]
## [1] 6 7 8
x[1,1]
## [1] 5
x[1, 2]
## [1] 8
x[1:2,3]
## [1] 7 8
x[3, -1]
## [1] 6 5 8
x[3, -(1:3)]
## [1] 8

4.13 Pegar vectores para formar matrices

Con los comandos cbind y rbind se pueden pegar varios vectores para formar una matriz. Si usamos cbind cada vector será una columna de la matriz formada. Con rbind será una fila:

y <- 1:3
z <- 4:6
A <- cbind(y, z)
A
##      y z
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
A[2,"z"]
## z 
## 5
B <-rbind(y, z)
B
##   [,1] [,2] [,3]
## y    1    2    3
## z    4    5    6
B["z",1]
## z 
## 4
colnames(B) <- c("a","b","c")
B
##   a b c
## y 1 2 3
## z 4 5 6
B["y","a"]
## [1] 1
B["y",]
## a b c 
## 1 2 3
B[,"a"]
## y z 
## 1 4

4.14 Cómo aplicar funciones a cada fila o columna de una matriz

Resulta bastante frecuente la necesidad de aplicar una función a cada una de las filas o columnas de una matriz. Para ello se usa el comando apply(). Este comando tiene tres argumentos:

El primer argumento es la matriz sobre la que se desea operar.
El segundo argumento es un 1 (si queremos operar sobre las filas) o un 2 (si queremos hacerlo sobre las columnas).
El tercer argumento es el nombre de la función que se desea aplicar a cada fila o columna.

En el siguiente ejemplo se calculan las medias de cada columna de x. Compara el resultado de apply con el de aplicar directamente el comando sobre la matriz. ¿Qué ocurre en este útimo caso? Como mean opera sobre vectores, al escribir mean(x) se considera la matriz como un vector y se calcula el promedio de todas sus entradas.

x
##      [,1] [,2] [,3] [,4]
## [1,]    5    8    7    6
## [2,]    6    5    8    7
## [3,]    7    6    5    8
mean(x)
## [1] 6.5
mean(x[1,])
## [1] 6.5
apply(x, 1, mean)
## [1] 6.5 6.5 6.5
apply(x, 2, mean)
## [1] 6.000000 6.333333 6.666667 7.000000
mean(x[,1])
## [1] 6

En el ejemplo siguiente se ordenan de menor a mayor cada una de las filas de una matriz. Observa con atención la dimensión de la matriz resultante:

x
##      [,1] [,2] [,3] [,4]
## [1,]    5    8    7    6
## [2,]    6    5    8    7
## [3,]    7    6    5    8
apply(x, 1, sort)
##      [,1] [,2] [,3]
## [1,]    5    5    5
## [2,]    6    6    6
## [3,]    7    7    7
## [4,]    8    8    8
apply(x, 2, sort)
##      [,1] [,2] [,3] [,4]
## [1,]    5    5    5    6
## [2,]    6    6    7    7
## [3,]    7    8    8    8

Si al aplicar la función sobre una columna o fila el resultado es otro vector, el resultado de apply será una matriz. En este caso, los resultados de la aplicación a cada columna o fila son las columnas de la matriz resultante.

4.15 Operaciones más habituales con matrices

En este apartado se resumen los comandos necesarios para llevar a cabo la operaciones con matrices más habituales:

4.15.1 Producto matricial: A %*% B

A %*% B
##       a  b  c
## [1,] 17 22 27
## [2,] 22 29 36
## [3,] 27 36 45

4.15.2 Producto elemento a elemento: A*B

A*A;B*B;x*x
##      y  z
## [1,] 1 16
## [2,] 4 25
## [3,] 9 36
##    a  b  c
## y  1  4  9
## z 16 25 36
##      [,1] [,2] [,3] [,4]
## [1,]   25   64   49   36
## [2,]   36   25   64   49
## [3,]   49   36   25   64

4.15.3 Traspuesta: t(A)

t(A*A);t(B*B);t(x*x)
##   [,1] [,2] [,3]
## y    1    4    9
## z   16   25   36
##   y  z
## a 1 16
## b 4 25
## c 9 36
##      [,1] [,2] [,3]
## [1,]   25   36   49
## [2,]   64   25   36
## [3,]   49   64   25
## [4,]   36   49   64

4.15.4 Determinante: det(A)

det(A%*%t(A));det(B%*%t(B));det(x%*%t(x))
## [1] 0
## [1] 54
## [1] 21696

4.15.5 Extraer la diagonal: diag(A)

diag(A%*%t(A));diag(B%*%t(B));diag(x%*%t(x))
## [1] 17 29 45
##  y  z 
## 14 77
## [1] 174 174 174

4.15.6 Resolver un sistema de ecuaciones lineales (\(Ax=b\)): solve(A,b)

A <- matrix(c(1,2,1,1,3,-5,1,5,6), ncol=3)
b <- c(2,11,29)
x <- solve(A,b)
A%*%c(1,-2,3)
##      [,1]
## [1,]    2
## [2,]   11
## [3,]   29

4.15.6.1 Inversa: solve(A)

solve(B%*%t(B));solve(A)
##            y          z
## y  1.4259259 -0.5925926
## z -0.5925926  0.2592593
##            [,1]       [,2]        [,3]
## [1,]  1.8695652 -0.4782609  0.08695652
## [2,] -0.3043478  0.2173913 -0.13043478
## [3,] -0.5652174  0.2608696  0.04347826
A%*%solve(A)
##              [,1]          [,2]          [,3]
## [1,] 1.000000e+00 -5.551115e-17 -2.081668e-17
## [2,] 0.000000e+00  1.000000e+00  0.000000e+00
## [3,] 4.440892e-16  0.000000e+00  1.000000e+00

4.15.6.2 Autovalores y autovectores (\(Alb=lb\)): eigen(A)

eigen(x%*%t(x));eigen(B%*%t(B));eigen(A%*%t(A))
## eigen() decomposition
## $values
## [1] 1.400000e+01 3.552714e-15 0.000000e+00
## 
## $vectors
##            [,1]       [,2]      [,3]
## [1,]  0.2672612  0.9636241 0.0000000
## [2,] -0.5345225  0.1482499 0.8320503
## [3,]  0.8017837 -0.2223748 0.5547002
## eigen() decomposition
## $values
## [1] 90.4026725  0.5973275
## 
## $vectors
##           [,1]       [,2]
## [1,] 0.3863177 -0.9223658
## [2,] 0.9223658  0.3863177
## eigen() decomposition
## $values
## [1] 71.416257 31.347447  0.236296
## 
## $vectors
##             [,1]       [,2]        [,3]
## [1,] -0.09484464 -0.2612512  0.96059997
## [2,] -0.47378819 -0.8368090 -0.27436357
## [3,] -0.87551656  0.4811428  0.04441089

4.16 Listas

Una lista es un vector de objetos de tipos distintos, que conviene agrupar en la misma estructura por diversas razones (por ejemplo, son un conjunto de resultados de un análisis estadístico de un conjunto de datos). Intuitivamente, es como una caja en la que se ponen objetos relacionados. Es importante comprender sus propiedades porque muchas funciones de R devuelven los resultados en forma de lista. Para crearlas se usa el comando list. En el siguiente ejemplo creamos una lista llamada milista con tres elementos llamados nombre, no.hijos y edades.hijos (este último es un vector de longitud 3):

milista <- list(nombre = "Pepe", no.hijos = 3, edades.hijos = c(4, 7, 9))

La estructura de una lista (los objetos que contiene la caja y de qué tipo son) se puede conocer con el comando str():

str(milista)
## List of 3
##  $ nombre      : chr "Pepe"
##  $ no.hijos    : num 3
##  $ edades.hijos: num [1:3] 4 7 9

4.17 Extraer elementos de una lista

Para extrer un elemento de una lista se usa nombre_lista$nombre_objeto si los elementos de la lista tienen nombre. También se puede usar un doble corchete y el número de orden del objeto dentro de la lista:

milista$nombre
## [1] "Pepe"
milista$no.hijos
## [1] 3
milista$edades.hijos
## [1] 4 7 9
milista[[1]]
## [1] "Pepe"
milista[[2]]
## [1] 3
milista[[3]]
## [1] 4 7 9
milista$edades.hijos[1]
## [1] 4
milista$edades.hijos[2]
## [1] 7
milista$edades.hijos[3]
## [1] 9

En el último ejemplo anterior hemos extraído el último elemento (que era un vector) y, dentro de este, la segunda coordenada. Para reflexionar sobre la diferencia entre un único corchete y un doble corchete:

¿Cuál es la diferencia entre milista[1] y milista[[1]]?

milista[1];milista[[1]]
## $nombre
## [1] "Pepe"
## [1] "Pepe"

¿Cuál es el resultado de milista[2:3]?

milista[2:3]
## $no.hijos
## [1] 3
## 
## $edades.hijos
## [1] 4 7 9

¿Y el resultado de milista[[2:3]]?

#milista[[2:3]]

4.18 Data frames

Un data frame es la estructura que se usa en R para los ficheros de datos correspondientes a una serie de variables medidas en cada sujeto o unidad bajo estudio. Intuitivamente podemos ver un data frame como una matriz con entradas que pueden ser de distintos tipos (números, palabras, etc.). Técnicamente son listas cuyos elementos son vectores de la misma longitud.

Para crearlos se utiliza el comando data.frame. En el siguiente ejemplo creamos uno llamado mifichero con dos vectores llamados edad y grupo. Los vectores (variables) son de la misma longitud pero son heterogéneos en el sentido de que el primero contiene números y el segundo letras.

x <- 7:9
y <- c("a", "b", "c")
mifichero <- data.frame(edad = x, grupo = y)
mifichero
##   edad grupo
## 1    7     a
## 2    8     b
## 3    9     c

Dado que los data frames son un tipo particular de listas, podemos aplicarles todos los comandos que hemos introducido en la sección anterior:

str(mifichero)
## 'data.frame':    3 obs. of  2 variables:
##  $ edad : int  7 8 9
##  $ grupo: chr  "a" "b" "c"
mifichero$edad
## [1] 7 8 9
mifichero$grupo
## [1] "a" "b" "c"
mifichero[[2]]
## [1] "a" "b" "c"

Al mismo tiempo, también admiten algunos de los comandos que se aplican a las matrices. Para extraer todas las variables correspondientes a la segunda observación (la segunda fila del fichero) podemos escribir:

mifichero[1, ]
##   edad grupo
## 1    7     a
mifichero[2, ]
##   edad grupo
## 2    8     b
mifichero[3, ]
##   edad grupo
## 3    9     c
mifichero[ ,1]
## [1] 7 8 9
mifichero[ ,2]
## [1] "a" "b" "c"

4.19 Aplicación de un comando a cada variable de un data frame

Si queremos aplicar el mismo comando a todas las variables de un fichero podemos usar dos comandos, lapply y sapply, que difieren en la estructura que tiene el resultado:

lapply para aplicar una función a cada elemento de una lista (el resultado es otra lista),
sapply actúa igual, pero el resultado es un vector o una matriz.

Como ejemplo tomamos el fichero faithful que contiene datos de duración y tiempo de espera entre erupciones del geyser Old faithful en Yellowstone. Si queremos obtener las principales medidas descriptivas de cada una de las dos variables del fichero:

sapply(faithful, summary)
##         eruptions  waiting
## Min.     1.600000 43.00000
## 1st Qu.  2.162750 58.00000
## Median   4.000000 76.00000
## Mean     3.487783 70.89706
## 3rd Qu.  4.454250 82.00000
## Max.     5.100000 96.00000
lapply(faithful, summary)
## $eruptions
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.600   2.163   4.000   3.488   4.454   5.100 
## 
## $waiting
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    43.0    58.0    76.0    70.9    82.0    96.0

4.20 Factores

Los factores son las estructuras que se utilizan para manejar las variables cualitativas en los análisis estadísticos. Se pueden contemplar como un vector al que se añade un poco más de información consistente en los distintos valores presentes en el vector, llamados niveles. Se crean usando el comando factor(). Veamos un ejemplo:

x <- c(2, 2, 3, 4, 2, 5)
x
## [1] 2 2 3 4 2 5
xfactor <- factor(x)
xfactor
## [1] 2 2 3 4 2 5
## Levels: 2 3 4 5

4.21 Aplicar una función para cada nivel de un factor

El fichero iris contiene los famosos datos de lirios de Fisher con medidas de la longitud y anchura del sépalo y pétalo de 150 lirios correspondientes a tres especies. Veamos las primeras observaciones del fichero:

head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa

La última variable es un factor que indica la especie a la que corresponde cada observación:

iris$Species
##   [1] setosa     setosa     setosa     setosa     setosa     setosa    
##   [7] setosa     setosa     setosa     setosa     setosa     setosa    
##  [13] setosa     setosa     setosa     setosa     setosa     setosa    
##  [19] setosa     setosa     setosa     setosa     setosa     setosa    
##  [25] setosa     setosa     setosa     setosa     setosa     setosa    
##  [31] setosa     setosa     setosa     setosa     setosa     setosa    
##  [37] setosa     setosa     setosa     setosa     setosa     setosa    
##  [43] setosa     setosa     setosa     setosa     setosa     setosa    
##  [49] setosa     setosa     versicolor versicolor versicolor versicolor
##  [55] versicolor versicolor versicolor versicolor versicolor versicolor
##  [61] versicolor versicolor versicolor versicolor versicolor versicolor
##  [67] versicolor versicolor versicolor versicolor versicolor versicolor
##  [73] versicolor versicolor versicolor versicolor versicolor versicolor
##  [79] versicolor versicolor versicolor versicolor versicolor versicolor
##  [85] versicolor versicolor versicolor versicolor versicolor versicolor
##  [91] versicolor versicolor versicolor versicolor versicolor versicolor
##  [97] versicolor versicolor versicolor versicolor virginica  virginica 
## [103] virginica  virginica  virginica  virginica  virginica  virginica 
## [109] virginica  virginica  virginica  virginica  virginica  virginica 
## [115] virginica  virginica  virginica  virginica  virginica  virginica 
## [121] virginica  virginica  virginica  virginica  virginica  virginica 
## [127] virginica  virginica  virginica  virginica  virginica  virginica 
## [133] virginica  virginica  virginica  virginica  virginica  virginica 
## [139] virginica  virginica  virginica  virginica  virginica  virginica 
## [145] virginica  virginica  virginica  virginica  virginica  virginica 
## Levels: setosa versicolor virginica

Supongamos que queremos calcular la media de las lóngitudes de los pétalos para cada una de las tres especies. Para ello podemos usar la funcion tapply(), que tiene tres argumentos:

El primero, la variable a la que queremos aplicar la función;
el segundo, el factor para cada uno de cuyos niveles vamos a calcular la función;
el tercero, la función que queremos calcular (en nuestro ejemplo, la media)
tapply(iris$Petal.Length, iris$Species, mean)
##     setosa versicolor  virginica 
##      1.462      4.260      5.552