-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbasics.qmd
702 lines (493 loc) · 36.8 KB
/
basics.qmd
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
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
# Lo Más Básico {#Básico}
Este capítulo proporciona una descripción general amplia del lenguaje R que lo ayudará a programar de inmediato. En él, construirás un par de dados virtuales que puedes usar para generar números aleatorios. No se preocupe si nunca ha programado antes; el capítulo le enseñará todo lo que necesita saber.
Para simular un par de dados, tendrás que destilar cada dado en sus características esenciales. No puede colocar un objeto físico, como un dado, en una computadora (bueno, no sin destornillar algunos tornillos), pero puede guardar *información* sobre el objeto en la memoria de su computadora.
¿Qué información debe guardar? En general, un dado tiene seis piezas importantes de información: cuando tiras un dado, solo puede dar como resultado uno de los seis números: 1, 2, 3, 4, 5 y 6. Puedes capturar las características esenciales de un dado guardando los números 1, 2, 3, 4, 5 y 6 como un grupo de valores en la memoria de su computadora.
Trabajemos primero en guardar estos números y luego consideremos un método para "lanzar" nuestro dado.
## La Interfaz de Usuario de R
Antes de que pueda pedirle a su computadora que guarde algunos números, necesitará saber cómo hablarle. Ahí es donde entran R y RStudio. RStudio le brinda una manera de comunicarse con su computadora. R le brinda un idioma para hablar. Para comenzar, abra RStudio tal como abriría cualquier otra aplicación en su computadora. Cuando lo haga, debería aparecer una ventana en su pantalla como la que se muestra en la Figura @fig-console.
```{r}
#| label: fig-console
#| echo: FALSE
#| fig.cap: >
#| Su computadora cumple con sus órdenes cuando escribe comandos R
#| en el indicador en la línea inferior del panel de la consola. No
#| olvides presionar la tecla Enter. Cuando abre RStudio por primera
#| vez, la consola aparece en el panel de su izquierda, pero puede
#| cambiar esto con File > Preferences en la barra de menú.
knitr::include_graphics("images/hopr_0101.png")
```
::: callout-important
Si aún no tiene R y RStudio instalados en su computadora--o no sabe de lo que estoy hablando-- visite el [Apéndice A](#starting). El apéndice le dará una descripción general de las dos herramientas gratuitas y le indicará cómo descargarlas.
:::
La interfaz de RStudio es simple. Escriba el código R en la línea inferior del panel de la consola de RStudio y luego haga clic en Entrar para ejecutarlo. El código que escribe se llama *comando*, porque ordenará a su computadora que haga algo por usted. La línea en la que lo escribe se llama *línea de comando*.
Cuando escribe un comando en la consola y presiona Enter, su computadora ejecuta el comando y le muestra los resultados. Luego, RStudio muestra un mensaje nuevo para su próximo comando. Por ejemplo, si escribe `1 + 1` y pulsa Enter, RStudio mostrará:
```
> 1 + 1
[1] 2
>
```
Notarás que aparece un `[1]` al lado de tu resultado. R solo le informa que esta línea comienza con el primer valor en su resultado. Algunos comandos devuelven más de un valor y sus resultados pueden llenar varias líneas. Por ejemplo, el comando `100:130` devuelve 31 valores; crea una secuencia de números enteros del 100 al 130. Observe que aparecen nuevos números entre corchetes al comienzo de la segunda y tercera líneas de salida. Estos números solo significan que la segunda línea comienza con el valor 14 en el resultado y la tercera línea comienza con el valor 25. En su mayoría, puede ignorar los números que aparecen entre corchetes:
```
> 100:130
[1] 100 101 102 103 104 105 106 107 108 109 110 111 112
[14] 113 114 115 116 117 118 119 120 121 122 123 124 125
[25] 126 127 128 129 130
```
::: callout-tip
El operador de dos puntos (`:`) devuelve todos los números enteros entre los dos números enteros especificados antes y después de los dos puntos. Es una manera fácil de crear una secuencia de números.
:::
::: callout-note
**¿R no es un idioma?**
Es posible que me escuche hablar de R en tercera persona. Por ejemplo, podría decir: "Dígale a R que haga esto" o "Dígale a R que haga aquello", pero, por supuesto, R no puede hacer nada; es solo un idioma. Esta forma de hablar es una forma abreviada de decir: "Dígale a su computadora que haga esto escribiendo un comando en el lenguaje R en su consola RStudio". Su computadora, y no R, hace el trabajo real.
¿Es esta abreviatura confusa y un poco perezosa de usar? Sí. ¿Lo usa mucha gente? Todos los que conozco, probablemente porque es muy conveniente.
:::
::: callout-note
**¿Cuándo compilamos?**
En algunos lenguajes, como C, Java y FORTRAN, debe compilar su código legible por humanos en un código legible por máquina (a menudo 1 y 0) antes de poder ejecutarlo. Si ha programado en un lenguaje de este tipo antes, puede preguntarse si tiene que compilar su código R antes de poder usarlo. La respuesta es no. R es un lenguaje de programación dinámico, lo que significa que R interpreta automáticamente su código a medida que lo ejecuta.
:::
Si escribe un comando incompleto y presiona Enter, R mostrará un `+` en la consola, lo que significa que R está esperando que escriba el resto de su comando. Termina el comando o presiona Escape para comenzar de nuevo:
```
> 5 -
+
+ 1
[1] 4
```
Si escribe un comando que R no reconoce, R devolverá un mensaje de error. Si alguna vez ve un mensaje de error, no entre en pánico. R solo le está diciendo que su computadora no pudo entender o hacer lo que le pidió que hiciera. Luego puede probar un comando diferente en la siguiente línea:
```
> 3 % 5
Error: unexpected input in "3 % 5"
>
```
Una vez que domines la línea de comando, puedes hacer fácilmente cualquier cosa en R que harías con una calculadora. Por ejemplo, podrías hacer algo de aritmética básica:
``` r
2 * 3
## 6
4 - 1
## 3
6 / (4 - 1)
## 2
```
¿Notaste algo diferente en este código? He dejado fuera los `>` y `[1]`. Esto hará que el código sea más fácil de copiar y pegar si desea colocarlo en su propia consola.
R trata el carácter del hashtag, `#`, de una manera especial; R no ejecutará nada que siga a un hashtag en una línea. Esto hace que los hashtags sean muy útiles para agregar comentarios y anotaciones a su código. Los humanos podrán leer los comentarios, pero su computadora los pasará por alto. El hashtag se conoce como *símbolo de comentario* en R.
En el resto del libro, usaré hashtags para mostrar los resultados de las lineas de código R. Usaré un solo hashtag para agregar mis propios comentarios y un hashtag doble, `##`, para mostrar los resultados del código. Evitaré mostrar `>` y `[1]` a menos que quiera que los mires.
::: callout-important
**Cancelar comandos**
Algunos comandos de R pueden tardar mucho tiempo en ejecutarse. Puede cancelar un comando una vez que ha comenzado presionando ctrl + c. Tenga en cuenta que R también puede tardar mucho tiempo en cancelar el comando.
:::
**Ejercicio 2.1 (Magia con Numeros)** Esa es la interfaz básica para ejecutar código R en RStudio. ¿Crees que lo tienes? Si es así, intente realizar estas sencillas tareas. Si ejecuta todo correctamente, debería terminar con el mismo número con el que comenzó:
1. Elige cualquier número y súmale 2.
2. Multiplica el resultado por 3.
3. Resta 6 de la respuesta.
4. Divide lo que obtienes por 3.
A lo largo del libro, pondré ejercicios en partes, como el de arriba. Seguiré cada ejercicio con una respuesta modelo, como la siguiente.
*Solución.* Puede comenzar con el número 10 y luego seguir los siguientes pasos:
``` r
10 + 2
## 12
12 * 3
## 36
36 - 6
## 30
30 / 3
## 10
```
## Objetos
Ahora que sabes cómo usar R, usémoslo para hacer un dado virtual. El operador `:` de hace un par de páginas le brinda una buena manera de crear un grupo de números del uno al seis. El operador `:` devuelve sus resultados como un **vector**, un conjunto unidimensional de números:
``` r
1:6
## 1 2 3 4 5 6
```
¡Eso es todo lo que hay sobre el aspecto de un dado virtual! Pero aún no has terminado. Ejecutar `1:6` generó un vector de números para que lo veas, pero no guardó ese vector en ninguna parte de la memoria de tu computadora. Lo que está viendo son básicamente las huellas de seis números que existieron brevemente y luego se fundieron de nuevo en la memoria RAM de tu computadora. Si desea volver a usar esos números, tendrá que pedirle a su computadora que los guarde en algún lugar. Puede hacerlo creando un *objeto* de R.
R le permite guardar datos almacenándolos dentro de un objeto R. ¿Qué es un objeto? Solo un nombre que puede usar para recuperar datos almacenados. Por ejemplo, puede guardar datos en un objeto como *`a`* o *`b`*. Siempre que R encuentre el objeto, lo reemplazará con los datos guardados en su interior, así:
``` r
a <- 1
a
## 1
a + 2
## 3
```
::: callout-note
**¿Qué acaba de suceder?**
1. Para crear un objeto R, elija un nombre y luego use el símbolo menor que, `<`, seguido de un signo menos, `-`, para guardar datos en él. Esta combinación parece una flecha, `<-`. R creará un objeto, le dará su nombre y almacenará en él lo que siga a la flecha. Entonces `a <- 1` almacena `1` en un objeto llamado `a`.
2. Cuando le preguntas a R qué hay en `a`, R te dice en la siguiente línea.
3. También puede usar su objeto en nuevos comandos R. Dado que `a` almacenó previamente el valor de `1`, ahora está agregando `1` a `2`.
:::
Entonces, para otro ejemplo, el siguiente código crearía un objeto llamado `dado` que contiene los números del uno al seis. Para ver lo que está almacenado en un objeto, simplemente escriba el nombre del objeto por sí mismo:
``` r
dado <- 1:6
dado
## 1 2 3 4 5 6
```
Cuando crea un objeto, el objeto aparecerá en el panel de Environment de RStudio, como se muestra en la Figura @fig-environment. Este panel le mostrará todos los objetos que ha creado desde que abrió RStudio.
```{r}
#| label: fig-environment
#| echo: FALSE
#| fig.cap: >
#| El panel de Environment de RStudio realiza un seguimiento de los objetos R que crea.
knitr::include_graphics("images/hopr_0102.png")
```
Puedes nombrar un objeto en R casi como quieras, pero hay algunas reglas. Primero, un nombre no puede comenzar con un número. Segundo, un nombre no puede usar algunos símbolos especiales, como `^`, `!`, `$`, `@`, `+`, `-`, `/`, or `*`:
| Buenos nombres | Nombres que causan error |
|----------------|--------------------------|
| a | 1trial |
| b | \$ |
| FOO | \^mean |
| my_var | 2nd |
| .day | !bad |
::: callout-warning
**Mayúsculas**
R distingue entre mayúsculas y minúsculas, por lo que `nombre` y `Nombre` se referirán a diferentes objetos:
`Nombre <- 1`\
`nombre <- 0`
`Nombre + 1`\
`## 2`
:::
Finalmente, R sobrescribirá cualquier información anterior almacenada en un objeto sin pedirle permiso. Por lo tanto, es una buena idea *no* usar nombres que ya están en uso:
``` r
my_number <- 1
my_number
## 1
my_number <- 999
my_number
## 999
```
Puedes ver qué nombres de objetos ya has usado con la función `ls`:
``` r
ls()
## "a" "dado" "my_number" "nombre" "Nombre"
```
También puede ver qué nombres ha utilizado examinando el panel de environment de RStudio.
Ahora tiene un dado virtual que está almacenado en la memoria de su computadora. Puedes acceder a él cuando quieras escribiendo la palabra *`dado`*. Entonces, ¿qué puedes hacer con este dado? Bastante. R reemplazará un objeto con su contenido siempre que el nombre del objeto aparezca en un comando. Entonces, por ejemplo, puedes hacer todo tipo de operaciones matemáticas con el dado. Las matemáticas no son tan útiles para lanzar dados, pero la manipulación de conjuntos de números será su día a día como científico de datos. Así que echemos un vistazo a cómo hacer eso:
``` r
dado - 1
## 0 1 2 3 4 5
dado / 2
## 0.5 1.0 1.5 2.0 2.5 3.0
dado * dado
## 1 4 9 16 25 36
```
Si eres un gran fanático del álgebra lineal (¿y quién no lo es?), puedes notar que R no siempre sigue las reglas de la multiplicación de matrices. En su lugar, R utiliza *ejecución por elementos*. Cuando manipulas un conjunto de números, R aplicará la misma operación a cada elemento del conjunto. Entonces, por ejemplo, cuando ejecuta *`dado - 1`*, R resta uno de cada elemento de `dado`.
Cuando usa dos o más vectores en una operación, R alineará los vectores y realizará una secuencia de operaciones individuales. Por ejemplo, cuando ejecuta *`dado * dado`*, R alinea los dos vectores `dado` y luego multiplica el primer elemento del vector 1 por el primer elemento del vector 2. R luego multiplica el segundo elemento del vector 1 por el segundo elemento del vector 2, y así sucesivamente, hasta que se hayan multiplicado todos los elementos. El resultado será un nuevo vector de la misma longitud que los dos primeros, como se muestra en la Figura @fig-elementwise.
```{r}
#| label: fig-elementwise
#| echo: FALSE
#| fig.cap: >
#| Cuando R realiza una ejecución por elementos, hace coincidir los vectores y
#| luego manipula cada par de elementos de forma independiente.
knitr::include_graphics("images/hopr_0103.png")
```
Si le da a R dos vectores de longitudes desiguales, R repetirá el vector más corto hasta que sea tan largo como el vector más largo y luego hará los cálculos, como se muestra en la Figura @fig-recycle. Este no es un cambio permanente: el vector más corto tendrá su tamaño original después de que R haga los cálculos. Si la longitud del vector largo no es divisible equitativamente por el vctor corto, R devolverá un mensaje de advertencia. Este comportamiento se conoce como *reciclado de vectores* y ayuda a R a realizar operaciones por elementos:
``` r
1:2
## 1 2
1:4
## 1 2 3 4
dado
## 1 2 3 4 5 6
dado + 1:2
## 2 4 4 6 6 8
dado + 1:4
## 2 4 6 8 6 8
Warning message:
In dado + 1:4 :
longer object length is not a multiple of shorter object length
```
```{r}
#| label: fig-recycle
#| echo: FALSE
#| fig.cap: >
#| R repetirá un vector corto para realizar operaciones por elementos con
#| dos vectores de longitud desigual.
knitr::include_graphics("images/hopr_0104.png")
```
Las operaciones basadas en elementos son una característica muy útil en R porque manipulan grupos de valores de forma ordenada. Cuando comience a trabajar con conjuntos de datos, las operaciones por elementos garantizarán que los valores de una observación o caso solo se emparejen con valores de la misma observación o caso. Las operaciones basadas en elementos también facilitan la escritura de sus propios programas y funciones en R.
Pero no creas que R ha renunciado a la multiplicación de matrices tradicional. Solo tienes que pedirlo cuando quieras. Puedes hacer multiplicaciones internas con el operador `%*%` y multiplicaciones externas con el operador `%o%`:
``` r
dado %*% dado
## 91
dado %o% dado
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 2 3 4 5 6
## [2,] 2 4 6 8 10 12
## [3,] 3 6 9 12 15 18
## [4,] 4 8 12 16 20 24
## [5,] 5 10 15 20 25 30
## [6,] 6 12 18 24 30 36
```
También puedes hacer cosas como transponer una matriz con `t` y tomar su determinante con `det`.
No se preocupe si no está familiarizado con estas operaciones. Son fáciles de buscar y no los necesitará para este libro.
Ahora que puede hacer operaciones matemáticas con su objeto `dado`, veamos cómo podría "tirarlo". Lanzar el dado requerirá algo más sofisticado que la aritmética básica; deberá seleccionar aleatoriamente uno de los valores del dado. Y para eso, necesitarás una *función*.
## Funciones
R viene con muchas funciones que puede usar para realizar tareas sofisticadas como el muestreo aleatorio. Por ejemplo, puede redondear un número con la función `round` o calcular su factorial con la función `factorial`. Usar una función es bastante simple. Simplemente escriba el nombre de la función y luego los datos sobre los que desea que opere la función entre paréntesis::
``` r
round(3.1415)
## 3
factorial(3)
## 6
```
Los datos que pasa a la función se denominan *argumento* de la función. El argumento puede ser datos sin procesar, un objeto R o incluso los resultados de otra función R. En este último caso, R trabajará desde la función más interna hacia la más externa, como en la Figura @fig-pemdas.
``` r
mean(1:6)
## 3.5
mean(dado)
## 3.5
round(mean(dado))
## 4
```
```{r}
#| label: fig-pemdas
#| echo: FALSE
#| fig.cap: >
#| Cuando vincula funciones, R las resolverá desde la operación más interna
#| hasta la más externa. Aquí R primero busca el dado, luego calcula la media
#| de uno a seis y luego redondea la media."}
knitr::include_graphics("images/hopr_0105.png")
```
Por suerte para nosotros, hay una función R que puede ayudar a "tirar" el dado. Puede simular una tirada del dado con la función `sample` de R. `sample` toma *dos* argumentos: un vector llamado `x` y un número llamado `size`. `sample` devolverá elementos de `size` del vector:
``` r
sample(x = 1:4, size = 2)
## 3 2
```
Para tirar el dado y obtener un número de vuelta, establezca `x` en `dado` y muestree un elemento de él. Obtendrá un número nuevo (quizás diferente) cada vez que lo haga rodar:
``` r
sample(x = dado, size = 1)
## 2
sample(x = dado, size = 1)
## 1
sample(x = dado, size = 1)
## 6
```
Muchas funciones de R toman múltiples argumentos que las ayudan a hacer su trabajo. Puede dar a una función tantos argumentos como desee siempre que separe cada argumento con una coma.
Es posible que hayas notado que establecí `dado` y `1` iguales a los nombres de los argumentos en `sample`, `x` y `size`. Cada argumento en cada función de R tiene un nombre. Puede especificar qué datos deben asignarse a qué argumento estableciendo un nombre igual a data, como en el código anterior. Esto se vuelve importante a medida que comienza a pasar múltiples argumentos a la misma función; los nombres lo ayudan a evitar pasar los datos incorrectos al argumento incorrecto. Sin embargo, el uso de nombres es opcional. Notará que los usuarios de R no suelen usar el nombre del primer argumento en una función. Por lo tanto, es posible que vea el código anterior escrito como:
``` r
sample(dado, size = 1)
## 2
```
A menudo, el nombre del primer argumento no es muy descriptivo y, de todos modos, suele ser obvio a qué se refiere el primer dato.
Pero, ¿cómo saber qué nombres de argumento usar? Si intenta usar un nombre que una función no espera, es probable que obtenga un error:
``` r
round(3.1415, corners = 2)
## Error in round(3.1415, corners = 2) : unused argument(s) (corners = 2)
```
Si no está seguro de qué nombres usar con una función, puede buscar los argumentos de la función con `args`. Para hacer esto, coloque el nombre de la función entre paréntesis detrás de `args`. Por ejemplo, puede ver que la función `round` toma dos argumentos, uno llamado `x` y otro llamado `digits`:
``` r
args(round)
## function (x, digits = 0)
## NULL
```
¿Notaste que `args` muestra que el argumento `digits` de `round` ya está establecido en 0? Con frecuencia, una función R tomará argumentos opcionales como `digits`. Estos argumentos se consideran opcionales porque vienen con un valor predeterminado. Puede pasar un nuevo valor a un argumento opcional si así lo desea, y R utilizará el valor predeterminado si no proporciona uno nuevo. Por ejemplo, "round" redondeará su número a 0 dígitos más allá del punto decimal de forma predeterminada. Para anular el valor predeterminado, proporcione su propio valor para `digits`:
``` r
round(3.1415)
## 3
round(3.1415, digits = 2)
## 3.14
```
Debe escribir los nombres de cada argumento después del primero o dos cuando llame a una función con múltiples argumentos. ¿Por qué? Primero, esto lo ayudará a usted y a otros a comprender su código. Por lo general, es obvio a qué argumento se refiere su primera entrada (y, a veces, también la segunda entrada). Sin embargo, necesitaría una memoria grande para recordar los argumentos tercero y cuarto de cada función R. En segundo lugar, y más importante, escribir los nombres de los argumentos evita errores.
Si no escribe los nombres de sus argumentos, R hará coincidir sus valores con los argumentos de su función por orden. Por ejemplo, en el siguiente código, el primer valor, `dado`, coincidirá con el primer argumento de `sample`, que se llama `x`. El siguiente valor, `1`, coincidirá con el siguiente argumento, `size`:
``` r
sample(dado, 1)
## 2
```
A medida que proporciona más argumentos, es más probable que su orden y el orden de R no coincidan. Como resultado, los valores pueden pasarse al argumento incorrecto. Los nombres de los argumentos evitan esto. R siempre hará coincidir un valor con el nombre de su argumento, sin importar dónde aparezca en el orden de los argumentos:
``` r
sample(size = 1, x = dado)
## 2
```
### Muestra con reemplazo
Si configura `size = 2`, puede *casi* simular un par de dados. Antes de ejecutar ese código, piense por un minuto por qué ese podría ser el caso. `sample` devolverá dos números, uno para cada dado:
``` r
sample(dado, size = 2)
## 3 4
```
Dije que esto "casi" funciona porque este método hace algo divertido. Si lo usa muchas veces, notará que el segundo dado nunca tiene el mismo valor que el primero, lo que significa que nunca obtendrá algo como un par de tres o un par de unos. ¿Qué esta pasando?
Por defecto, `sample` construye una muestra *sin reemplazo*. Para ver lo que esto significa, imagina que `sample` coloca todos los valores de `dado` en un frasco o urna. Luego imagine que `sample` alcanza el frasco y extrae valores uno por uno para construir su muestra. Una vez que se ha extraído un valor del frasco, `sample` lo deja a un lado. El valor no vuelve al frasco, por lo que no se puede volver a extraer. Entonces, si `sample` selecciona un seis en su primer sorteo, no podrá seleccionar un seis en el segundo sorteo; seis ya no está en el frasco para ser seleccionado. Aunque `sample` crea su muestra electrónicamente, sigue este comportamiento aparentemente físico.
Un efecto secundario de este comportamiento es que cada sorteo depende de los sorteos anteriores. Sin embargo, en el mundo real, cuando lanzas un par de dados, cada dado es independiente del otro. Si el primer dado sale seis, no impide que el segundo dado salga seis. De hecho, no influye en el segundo dado de ninguna manera. Puede recrear este comportamiento en `sample` agregando el argumento `replace = TRUE`:
``` r
sample(dado, size = 2, replace = TRUE)
## 5 5
```
El argumento `replace = TRUE` hace que `sample` muestree *con reemplazo*. Nuestro ejemplo de frasco proporciona una buena manera de comprender la diferencia entre el muestreo con reemplazo y sin reemplazo. Cuando `sample` usa reemplazo, extrae un valor del frasco y registra el valor. Luego vuelve a poner el valor en el frasco. En otras palabras, `sample` *reemplaza* cada valor después de cada sorteo. Como resultado, `sample` puede seleccionar el mismo valor en el segundo sorteo. Cada valor tiene la posibilidad de ser seleccionado cada vez. Es como si cada sorteo fuera el primer sorteo.
El muestreo con reemplazo es una manera fácil de crear *muestras aleatorias independientes*. Cada valor en su muestra será una muestra de tamaño uno que es independiente de los otros valores. Esta es la forma correcta de simular un par de dados.
``` r
sample(dado, size = 2, replace = TRUE)
## 2 4
```
Felicítate a ti mismo; ¡Acabas de ejecutar tu primera simulación en R! Ahora tiene un método para simular el resultado de lanzar un par de dados. Si desea sumar los dados, puede ingresar su resultado directamente en la función `sum`:
``` r
dados <- sample(dado, size = 2, replace = TRUE)
dados
## 2 4
sum(dados)
## 6
```
¿Qué pasaría si llamas `dados` varias veces? ¿Generaría R un nuevo par de valores de dados cada vez? Probemos:
``` r
dados
## 2 4
dados
## 2 4
dados
## 2 4
```
No. Cada vez que llame a `dados`, R le mostrará el resultado de esa vez que llamó a `sample` y guardó la salida en `dados`. R no volverá a ejecutar `sample(dado, 2, replace = TRUE)` para crear una nueva tirada de dados. Esto es un alivio en cierto modo. Una vez que guarda un conjunto de resultados en un objeto de R, esos resultados no cambian. La programación sería bastante difícil si los valores de sus objetos cambiaran cada vez que los llama.
Sin embargo, *sería* conveniente tener un objeto que pueda volver a tirar los dados cada vez que lo llames. Puede hacer tal objeto escribiendo su propia función de R.
## Escribiendo Sus Propias Funciones {#Escribir-funciones}
Para recapitular, ya tiene un código de R en funcionamiento que simula lanzar un par de dados:
``` r
dado <- 1:6
dados <- sample(dado, size = 2, replace = TRUE)
sum(dados)
```
Puede volver a escribir este código en la consola en cualquier momento que desee volver a tirar los dados. Sin embargo, esta es una forma incómoda de trabajar con el código. Sería más fácil usar su código si lo envolviera en su propia función, que es exactamente lo que haremos ahora. Vamos a escribir una función llamada `tirar` que puedes usar para lanzar tus dados virtuales. Cuando hayas terminado, la función funcionará así: cada vez que llames a `tirar()`, R devolverá la suma de tirar dos dados:
``` r
tirar()
## 8
tirar()
## 3
tirar()
## 7
```
Las funciones pueden parecer misteriosas o sofisticadas, pero son solo otro tipo de objeto de R. En lugar de contener datos, contienen código. Este código se almacena en un formato especial que facilita su reutilización en situaciones nuevas. Puede escribir sus propias funciones recreando este formato.
### El Constructor de Funciones
Cada función en R tiene tres partes básicas: un nombre, un cuerpo de código y un conjunto de argumentos. Para crear su propia función, debe replicar estas partes y almacenarlas en un objeto de R, esto lo puede hacer con la función `function`. Para hacer esto, llama a `function()` y sigue con un par de llaves, `{}`:
``` r
mi_funcion <- function() {}
```
`function` construirá una función a partir de cualquier código R que coloque entre las llaves. Por ejemplo, puede convertir su código de dados en una función llamando:
``` r
tirar <- function() {
dado <- 1:6
dados <- sample(dado, size = 2, replace = TRUE)
sum(dados)
}
```
::: callout-note
Observe que he aplicado sangría a cada línea de código entre las llaves. Esto hace que el código sea más fácil de leer para usted y para mí, pero no tiene impacto en cómo se ejecuta el código. R ignora los espacios y los saltos de línea y ejecuta una expresión completa a la vez.
:::
Simplemente presione la tecla Enter entre cada línea después de la primera llave, `{`. R esperará a que escribas la última llave, `}`, antes de responder.
No olvide guardar la salida de `function` en un objeto de R. Este objeto se convertirá en su nueva función. Para usarlo, escriba el nombre del objeto seguido de un paréntesis de apertura y cierre:
``` r
tirar()
## 9
```
Puede pensar en los paréntesis como el "disparador" que hace que R ejecute la función. Si escribe el nombre de una función *sin* los paréntesis, R le mostrará el código que está almacenado dentro de la función. Si escribe el nombre *con* los paréntesis, R ejecutará ese código:
``` r
tirar
## function() {
## dado <- 1:6
## dados <- sample(dado, size = 2, replace = TRUE)
## sum(dados)
## }
tirar()
## 6
```
El código que coloca dentro de su función se conoce como el *cuerpo* de la función. Cuando ejecuta una función en R, R ejecutará todo el código en el cuerpo y luego devolverá el resultado de la última línea de código. Si la última línea de código no devuelve un valor, tampoco lo hará su función, por lo que debe asegurarse de que su última línea de código devuelva un valor. Una forma de verificar esto es pensar en lo que sucedería si ejecutara el cuerpo del código línea por línea en la consola. ¿Mostraría R un resultado después de la última línea, o no?
Aquí hay un código que mostraría un resultado:
``` r
dados
1 + 1
sqrt(2)
```
Y aquí hay un código que no:
``` r
dados <- sample(dado, size = 2, replace = TRUE)
dos <- 1 + 1
a <- sqrt(2)
```
¿Notas el patrón? Estas líneas de código no devuelven un valor a la línea de comando; guardan un valor a un objeto.
## Argumentos
¿Qué pasa si eliminamos una línea de código de nuestra función y cambiamos el nombre `dado` a `bones`, así?
``` r
tirar2 <- function() {
dados <- sample(bones, size = 2, replace = TRUE)
sum(dados)
}
```
Ahora obtendré un error cuando ejecute la función. La función necesita el objeto `bones` para hacer su trabajo, pero no se puede encontrar ningún objeto llamado `bones`:
``` r
tirar2()
## Error in sample(bones, size = 2, replace = TRUE) :
## object 'bones' not found
```
Puedes proporcionar `bones` cuando llamas a `tirar2` si conviertes a `bones` en un argumento de la función. Para hacer esto, pon el nombre `bones` entre los paréntesis que siguen a `function` cuando definas `tirar2`:
``` r
tirar2 <- function(bones) {
dados <- sample(bones, size = 2, replace = TRUE)
sum(dados)
}
```
Ahora `tirar2` funcionará siempre y cuando proporciones `bones` cuando llames a la función. Puede aprovechar esto para lanzar diferentes tipos de dados cada vez que llamas `tirar2`. ¡Calabozos y Dragones, aquí vamos!
Recuerda, estamos lanzando pares de dados:
``` r
tirar2(bones = 1:4)
## 3
tirar2(bones = 1:6)
## 10
tirar2(1:20)
## 31
```
Tenga en cuenta que `tirar2` seguirá dando un error si no proporciona un valor para el argumento `bones` cuando llame a `tirar2`:
``` r
tirar2()
## Error in sample(bones, size = 2, replace = TRUE) :
## argument "bones" is missing, with no default
```
Puede evitar este error dando al argumento `bones` un valor predeterminado. Para hacer esto, establece `bones` igual a un valor cuando definas `tirar2`:
``` r
tirar2 <- function(bones = 1:6) {
dados <- sample(bones, size = 2, replace = TRUE)
sum(dados)
}
```
Ahora puede proporcionar un nuevo valor para `bones` si lo desea, y `tirar2` usará el valor predeterminado si no lo desea:
``` r
tirar2()
## 9
```
Puede dar a sus funciones tantos argumentos como desee. Simplemente enumere sus nombres, separados por comas, entre los paréntesis que siguen a `function`.Cuando se ejecuta la función, R reemplazará cada nombre de argumento en el cuerpo de la función con el valor que el usuario proporciona para el argumento. Si el usuario no proporciona un valor, R reemplazará el nombre del argumento con el valor predeterminado del argumento (si definió uno).
Para resumir, `function` te ayuda a construir tus propias funciones de R. Usted crea un cuerpo de código para que su función se ejecute escribiendo código entre las llaves que siguen a `function`. Usted crea argumentos para que su función los use proporcionando sus nombres entre los paréntesis que siguen a `function`. Finalmente, le da un nombre a su función guardando su salida en un objeto de R, como se muestra en la Figura @fig-functions.
Una vez que haya creado su función, R la tratará como cualquier otra función en R. Piense en lo útil que es. ¿Alguna vez ha intentado crear una nueva opción de Excel y agregarla a la barra de menú de Microsoft? ¿O una nueva animación de diapositivas y agregarla a las opciones de Powerpoint? Cuando trabajas con un lenguaje de programación, puedes hacer este tipo de cosas. A medida que aprenda a programar en R, podrá crear herramientas nuevas, personalizadas y reproducibles para usted cuando lo desee. [Proyecto 3: Máquina Tragamonedas](#slots) te enseñará mucho más sobre escribir funciones en R.
```{r}
#| label: fig-functions
#| echo: FALSE
#| fig.cap: >
#| Cada función en R tiene las mismas partes y puede usar `function` para
#| crear estas partes. Asigne el resultado a un nombre, para que pueda
#| llamar a la función más tarde.
knitr::include_graphics("images/hopr_0106.png")
```
## Scripts
¿Qué pasa si quieres editar `tirar2` de nuevo? Podría regresar y volver a escribir cada línea de código en `tirar2`, pero sería mucho más fácil si tuviera un borrador del código para empezar. Puede crear un borrador de su código a medida que avanza utilizando un *script* de R. Un script de R es solo un archivo de texto sin formato en el que guarda el código R. Puede abrir un script de R en RStudio yendo a `File> New File> R script` en la barra de menú. RStudio luego abrirá un script nuevo sobre el panel de su consola, como se muestra en la Figura @fig-script.
Le recomiendo encarecidamente que escriba y edite todo su código de R en un script antes de ejecutarlo en la consola. ¿Por qué? Este hábito crea un registro reproducible de su trabajo. Cuando termine el día, puede guardar su secuencia de comandos y luego usarla para volver a ejecutar todo el análisis al día siguiente. Los scripts también son muy útiles para editar y corregir su código, y hacen una buena copia de su trabajo para compartir con otros. Para guardar un script, haga clic en el panel de scripts y luego vaya a `File > Save as` en la barra de menú.
```{r}
#| label: fig-script
#| echo: FALSE
#| fig.cap: >
#| Cuando abre un R Script (File > New File > R Script in the menu bar),
#| RStudio crea un cuarto panel encima de la consola donde puede escribir
#| y editar su código
knitr::include_graphics("images/hopr_0107.png")
```
RStudio viene con muchas funciones integradas que facilitan el trabajo con scripts. Primero, puede ejecutar automáticamente una línea de código en un script haciendo clic en el botón Run, como se muestra en la Figura @fig-run.
R ejecutará cualquier línea de código en la que esté el cursor. Si tiene una sección completa resaltada, R ejecutará el código resaltado. Como alternativa, puede ejecutar todo el script haciendo clic en el botón Source. ¿No te gusta hacer clic en los botones? Puede usar Control + Enter como acceso directo para el botón Ejecutar. En Mac, eso sería Comando + Enter.
```{r}
#| label: fig-run
#| echo: FALSE
#| fig.cap: >
#| Puede ejecutar una parte resaltada del código en su secuencia de
#| comandos si hace clic en el botón Run en la parte superior del
#| panel de Scripts. Puede ejecutar todo el script haciendo clic
#| en el botón Source.
knitr::include_graphics("images/hopr_0108.png")
```
Si no está convencido acerca de los scripts, pronto lo estará. Se convierte en una molestia escribir código de varias líneas en la línea de comando de una sola línea de la consola. Evitemos ese dolor de cabeza y abramos su primer script ahora antes de pasar al siguiente capítulo.
::: callout-tip
**Extraer función**
RStudio viene con una herramienta que puede ayudarlo a crear funciones. Para usarlo, resalte las líneas de código en su secuencia de comandos R que desea convertir en una función. Luego haga clic en `Code > Extract Function` en la barra de menú. RStudio le pedirá un nombre de función para usar y luego envolverá su código en una llamada de `function`. Escaneará el código en busca de variables indefinidas y las usará como argumentos.
Es posible que desee volver a comprobar el trabajo de RStudio. Asume que su código es correcto, por lo que si hace algo sorprendente, es posible que tenga un problema en su código.
:::
## Resumen
Ya has cubierto mucho terreno. Ahora tiene un dado virtual almacenado en la memoria de su computadora, así como su propia función de R que lanza un par de dados. También ha comenzado a hablar el lenguaje R.
Como has visto, R es un lenguaje que puedes usar para hablar con tu computadora. Escribes comandos en R y los ejecutas en la línea de comandos para que tu computadora los lea. Su computadora a veces responderá--por ejemplo, cuando cometa un error--pero generalmente solo hace lo que le pide y luego muestra el resultado.
Los dos componentes más importantes del lenguaje R son los objetos, que almacenan datos, y las funciones, que manipulan datos. R también usa una gran cantidad de operadores como `+`, `-`, `*`, `/` y `<-` para realizar tareas básicas. Como científico de datos, usará objetos de R para almacenar datos en la memoria de su computadora y usará funciones para automatizar tareas y realizar cálculos complicados. Examinaremos los objetos con más profundidad más adelante en [Proyecto 2: Baraja de Cartas](#cards) y profundizaremos en las funciones en [Proyecto 3: Máquina Tragamonedas](#slots). El vocabulario que ha desarrollado aquí hará que cada uno de esos proyectos sea más fácil de entender. Sin embargo, aún no hemos terminado con tus dados.
En [Paquetes y páginas de ayuda](#packages), , ejecutará algunas simulaciones con sus dados y construirá sus primeros gráficos en R. También verá dos de los componentes más útiles del lenguaje R: *Paquetes* de R, que son colecciones de funciones escritas por la talentosa comunidad de desarrolladores de R, y documentación de R, que es una colección de páginas de ayuda integradas en R que explica cada función y conjunto de datos en el lenguaje.