-
Notifications
You must be signed in to change notification settings - Fork 0
/
objects.qmd
944 lines (676 loc) · 49.5 KB
/
objects.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
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
# Objectos de R {#objects}
En este capítulo, usará R para armar una baraja de 52 cartas.
Comenzará construyendo objetos R simples que representan naipes y luego avanzará hasta una tabla de datos completa. En resumen, creará el equivalente a una hoja de cálculo de Excel desde cero. Cuando hayas terminado, tu mazo de cartas se verá así:
``` r
cara palo valor
rey picas 13
reina picas 12
jota picas 11
diez picas 10
nueve picas 9
ocho picas 8
...
```
¿Necesita crear un conjunto de datos desde cero para usarlo en R? Para nada. Puede cargar la mayoría de los conjuntos de datos en R con un simple paso, consulte [Cargar datos](#loading). Pero este ejercicio le enseñará cómo R almacena datos y cómo puede ensamblar, o desensamblar, sus propios conjuntos de datos. También aprenderá sobre los diversos tipos de objetos disponibles para usar en R (¡no todos los objetos de R son iguales!). Considere este ejercicio como un rito de iniciación; al hacerlo, se convertirá en un experto en el almacenamiento de datos en R.
Comenzaremos con lo más básico. El tipo de objeto más simple en R es un *vector atómico*. Los vectores atómicos no tienen energía nuclear, pero son muy simples y aparecen en todas partes. Si observa lo suficientemente de cerca, verá que la mayoría de las estructuras en R se construyen a partir de vectores atómicos.
## Vectores Atómicos
Un vector atómico es solo un simple vector de datos. De hecho, ya ha creado un vector atómico, su objeto `dado` del [Proyecto 1: Dados Ponderados](#dice). Puede hacer un vector atómico agrupando algunos valores de datos con `c`:
``` r
dado <- c(1, 2, 3, 4, 5, 6)
dado
## 1 2 3 4 5 6
is.vector(dado)
## TRUE
```
::: callout-note
**is.vector**
`is.vector` comprueba si un objeto es un vector atómico. Devuelve `TRUE` si el objeto es un vector atómico y `FALSE` en caso contrario.
:::
También puedes hacer un vector atómico con un solo valor. R guarda valores individuales como un vector atómico de longitud 1:
``` r
cinco <- 5
cinco
## 5
is.vector(cinco)
## TRUE
length(cinco)
## 1
length(dado)
## 6
```
::: callout-note
**length**
`length` devuelve la longitud de un vector atómico.
:::
Cada vector atómico almacena sus valores como un vector unidimensional y cada vector atómico solo puede almacenar un tipo de datos. Puede guardar diferentes tipos de datos en R utilizando diferentes tipos de vectores atómicos. En total, R reconoce seis tipos básicos de vectores atómicos: *dobles*, *enteros*, *caracteres*, *lógicos*, *complejos* y *sin procesar*.
Para crear su mazo de cartas, necesitará usar diferentes tipos de vectores atómicos para guardar diferentes tipos de información (texto y números). Puede hacer esto usando algunas convenciones simples cuando ingresa sus datos. Por ejemplo, puede crear un vector de números enteros al incluir una `L` mayúscula con su entrada. Puede crear un vector de caracteres encerrando su entrada entre comillas:
``` r
ent <- 1L
text <- "as"
```
Cada tipo de vector atómico tiene su propia convención (descrita a continuación). R reconocerá la convención y la usará para crear un vector atómico del tipo apropiado. Si desea crear vectores atómicos que tengan más de un elemento, puede combinar un elemento con la función `c` de [Paquetes y Páginas de ayuda](#packages). Use la misma convención con cada elemento:
``` r
ent <- c(1L, 5L)
text <- c("as", "corazon")
```
Quizás se pregunte por qué R usa múltiples tipos de vectores. Los tipos de vectores ayudan a que R se comporte como cabría esperar. Por ejemplo, R hará operaciones matemáticas con vectores atómicos que contienen números, pero no con vectores atómicos que contienen cadenas de caracteres:
``` r
sum(ent)
## 6
sum(text)
## Error in sum(text) : invalid 'type' (character) of argument
```
¡Pero nos estamos adelantando! Prepárese para saludar a los seis tipos de vectores atómicos en R.
### Dobles
Un vector doble almacena números regulares. Los números pueden ser positivos o negativos, grandes o pequeños, y tener dígitos a la derecha del lugar decimal o no. En general, R guardará cualquier número que escriba en R como un doble. Entonces, por ejemplo, el dado que hiciste en [Proyecto 1: Dados Ponderados](#dice) era un objeto doble:
``` r
dado <- c(1, 2, 3, 4, 5, 6)
dado
## 1 2 3 4 5 6
```
Por lo general, sabrá con qué tipo de objeto está trabajando en R (será obvio), pero también puede preguntarle a R qué tipo de objeto es un objeto con `typeof`. Por ejemplo:
``` r
typeof(dado)
## "double"
```
Algunas funciones de R se refieren a los dobles como "numéricos", y yo haré lo mismo con frecuencia. Doble es un término informático. Se refiere a la cantidad específica de bytes que usa su computadora para almacenar un número, pero encuentro que "numérico" es mucho más intuitivo cuando se hace ciencia de datos.
### Enteros
Los vectores enteros almacenan números enteros, números que se pueden escribir sin un componente decimal. Como científico de datos, no usará el tipo de número entero con mucha frecuencia porque puede guardar los números enteros como un objeto doble.
Puede crear específicamente un número entero en R escribiendo un número seguido de una `L` mayúscula. Por ejemplo:
``` r
ent <- c(-1L, 2L, 4L)
ent
## -1 2 4
typeof(ent)
## "integer"
```
Tenga en cuenta que R no guardará un número como un entero a menos que incluya `L`. Los números enteros sin la `L` se guardarán como dobles. La única diferencia entre `4` y `4L` es cómo R guarda el número en la memoria de tu computadora. Los números enteros se definen con mayor precisión en la memoria de su computadora que los dobles (a menos que el número entero sea *muy* grande o pequeño).
¿Por qué guardaría sus datos como un número entero en lugar de un doble? A veces, una diferencia en la precisión puede tener efectos sorprendentes. Su computadora asigna 64 bits de memoria para almacenar cada doble en un programa de R. Esto permite mucha precisión, pero algunos números no se pueden expresar exactamente en 64 bits, el equivalente a una secuencia de 64 unos y ceros. Por ejemplo, el número $\pi$ contiene una secuencia interminable de dígitos a la derecha del lugar decimal. Su computadora debe redondear $\pi$ a algo cercano, pero no exactamente igual a $\pi$ para almacenar $\pi$ en su memoria. Muchos números decimales comparten esta característica.
Como resultado, cada doble tiene una precisión de unos 16 dígitos significativos. Esto introduce un pequeño error. En la mayoría de los casos, este error de redondeo pasará desapercibido. Sin embargo, en algunas situaciones, el error de redondeo puede causar resultados sorprendentes. Por ejemplo, puede esperar que el resultado de la siguiente expresión sea cero, pero no lo es:
``` r
sqrt(2)^2 - 2
## 4.440892e-16
```
La raíz cuadrada de dos no se puede expresar exactamente en 16 dígitos significativos. Como resultado, R tiene que redondear la cantidad y la expresión se resuelve en algo muy cercano a cero, pero no del todo.
Estos errores se conocen como errores de *punto flotante*, y hacer aritmética en estas condiciones se conoce como *aritmética de punto flotante*. La aritmética de punto flotante no es una característica de R; es una característica de la programación de computadoras. Por lo general, los errores de punto flotante no serán suficientes para arruinar su día. Solo tenga en cuenta que pueden ser la causa de resultados sorprendentes.
Puede evitar errores de punto flotante si evita los decimales y solo usa números enteros. Sin embargo, esta no es una opción en la mayoría de las situaciones de ciencia de datos. No puedes hacer muchas matemáticas con números enteros antes de que necesites un número no entero para expresar el resultado. Afortunadamente, los errores causados por la aritmética de punto flotante suelen ser insignificantes (y cuando no lo son, son fáciles de detectar). Como resultado, generalmente usará dobles en lugar de números enteros como científico de datos.
### Caracteres
Un vector de caracteres almacena pequeños fragmentos de texto. Puede crear un vector de caracteres en R escribiendo un carácter o una cadena de caracteres entre comillas:
``` r
text <- c("Hola", "Mundo")
text
## "Hola" "Mundo"
typeof(text)
## "character"
typeof("Hola")
## "character"
```
Los elementos individuales de un vector de caracteres se conocen como *cadenas*. Tenga en cuenta que una cadena puede contener más que solo letras. También puede ensamblar una cadena de caracteres a partir de números o símbolos.
**Ejercicio 5.1 (Carácter or Número)** ¿Puedes encontrar la diferencia entre una cadena de caracteres y un número? Aquí hay una prueba: ¿Cuáles de estos son cadenas de caracteres y cuáles son números? `1`, `"1"`, `"uno"`.
*Solución.* `"1"` y `"uno"` son ambos cadenas de caracteres.
Las cadenas de caracteres pueden contener caracteres numéricos, pero eso no los convierte en numéricos. Son solo cadenas que tienen números en ellas. Puede distinguir cadenas de números reales porque las cadenas vienen entre comillas. De hecho, todo lo que esté entre comillas en R se tratará como una cadena de caracteres, independientemente de lo que aparezca entre las comillas.
Es fácil confundir objetos de R con cadenas de caracteres. ¿Por qué? Porque ambos aparecen como fragmentos de texto en código de R. Por ejemplo, `x` es el nombre de un objeto R llamado "x", `"x"` es una cadena de caracteres que contiene el carácter "x". Uno es un objeto que contiene datos sin procesar, el otro es un fragmento de datos sin procesar en sí mismo.
Espere un error cada vez que olvide sus comillas; R comenzará a buscar un objeto que probablemente no exista.
### Lógicos
Los vectores lógicos almacenan `TRUE` y `FALSE`, la forma de R de datos booleanos. Los lógicos son muy útiles para hacer cosas como comparaciones:
``` r
3 > 4
## FALSE
```
Cada vez que escriba `TRUE` o `FALSE` en letras mayúsculas (sin comillas), R tratará su entrada como datos lógicos. R también asume que `T` y `F` son abreviaturas de `TRUE` y `FALSE`, a menos que se definan en otra parte (por ejemplo, 'T \<- 500'). Dado que el significado de `T` y `F` puede cambiar, es mejor quedarse con `TRUE` y `FALSE`:
``` r
logico <- c(TRUE, FALSE, TRUE)
logico
## TRUE FALSE TRUE
typeof(logico)
## "logical"
typeof(F)
## "logical"
```
### Complejo y Sin Procesar
Dobles, enteros, caracteres y lógicos son los tipos más comunes de vectores atómicos en R, pero R también reconoce dos tipos más: complejos y sin procesar. Es dudoso que alguna vez los use para analizar datos, pero aquí están por el bien de la minuciosidad.
Los vectores complejos almacenan números complejos. Para crear un vector complejo, agregue un término imaginario a un número con `i`:
``` r
comp <- c(1 + 1i, 1 + 2i, 1 + 3i)
comp
## 1+1i 1+2i 1+3i
typeof(comp)
## "complex"
```
Los vectores sin procesar almacenan bytes de datos sin procesar. Hacer vectores sin procesar se vuelve complicado, pero puedes hacer un vector sin procesar vacío de longitud *n* con `raw(n)`. Consulte la página de ayuda de `raw` para obtener más opciones al trabajar con este tipo de datos:
``` r
raw(3)
## 00 00 00
typeof(raw(3))
## "raw"
```
**Ejercicio 5.2 (Vector de Cartas)** Cree un vector atómico que almacene solo los nombres de las caras de las cartas en una escalera real, por ejemplo, el as de picas, el rey de picas, la reina de picas, la jota de picas y el diez de picas. El nombre de la cara del as de picas sería "as" y "picas" es el palo.
¿Qué tipo de vector usarás para guardar los nombres?
*Solución.* Un vector de caracteres es el tipo de vector atómico más apropiado para guardar los nombres de las cartas. Puedes crear uno con la función `c` si pones cada nombre entre comillas:
``` r
mano <- c("as", "rey", "reina", "jota", "diez")
mano
## "as" "rey" "reina" "jota" "diez"
typeof(mano)
## "character"
```
Esto crea un grupo unidimensional de nombres de cartas. ¡Excelente trabajo! Ahora hagamos una estructura de datos más sofisticada, una tabla bidimensional de nombres de cartas y palos. Puede construir un objeto más sofisticado a partir de un vector atómico dándole algunos atributos y asignándole una clase.
## Atributos {#attributes}
Un atributo es una pieza de información que puede adjuntar a un vector atómico (o cualquier objeto de R). El atributo no afectará ninguno de los valores del objeto y no aparecerá cuando muestre su objeto. Puede pensar en un atributo como "metadatos"; es solo un lugar conveniente para colocar información asociada con un objeto. R normalmente ignorará estos metadatos, pero algunas funciones de R verificarán atributos específicos. Estas funciones pueden usar los atributos para hacer cosas especiales con los datos.
Puedes ver qué atributos tiene un objeto con `attributes`. `attributes` devolverá `NULL` si un objeto no tiene atributos. Un vector atómico, como `dado`, no tendrá ningún atributo a menos que le des alguno:
``` r
attributes(dado)
## NULL
```
::: callout-tip
**NULL**
R usa `NULL` para representar el conjunto nulo, un objeto vacío. `NULL` a menudo es devuelto por funciones cuyos valores no están definidos. Puede crear un objeto `NULL` escribiendo `NULL` en letras mayúsculas.
:::
### Nombres {#names}
Los atributos más comunes para dar un vector atómico son nombres, dimensiones (dim) y clases. Cada uno de estos atributos tiene su propia función auxiliar que puede usar para otorgar atributos a un objeto. También puede usar las funciones auxiliares para buscar el valor de estos atributos para los objetos que ya los tienen. Por ejemplo, puedes buscar el valor del atributo de nombres de `dado` con `names`:
``` r
names(dado)
## NULL
```
`NULL` significa que `dado` no tiene un atributo de nombres. Puedes darle uno a `dado` asignando un vector de caracteres a la salida de `names`. El vector debe incluir un nombre para cada elemento en `dado`:
``` r
names(dado) <- c("uno", "dos", "tres", "cuatro", "cinco", "seis")
```
Ahora `dado` tiene el atributo nombres:
``` r
names(dado)
## "uno" "dos" "tres" "cuatro" "cinco" "seis"
attributes(dado)
## $names
## [1] "uno" "dos" "tres" "cuatro" "cinco" "seis"
```
R mostrará los nombres sobre los elementos de `dado` cada vez que mires el vector:
``` r
dado
## uno dos tres cuatro cinco seis
## 1 2 3 4 5 6
```
Sin embargo, los nombres no afectarán los valores reales del vector, ni los nombres se verán afectados cuando manipule los valores del vector:
``` r
dado + 1
## uno dos tres cuatro cinco seis
## 2 3 4 5 6 7
```
También puede usar `names` para cambiar el atributo de nombres o eliminarlo todo junto. Para cambiar los nombres, asigna un nuevo conjunto de etiquetas a `names`:
``` r
names(dado) <- c("one", "two", "three", "four", "five", "six")
dado
## one two three four five six
## 1 2 3 4 5 6
```
Para eliminar el atributo de nombres, configúrelo en `NULL`:
``` r
names(dado) <- NULL
dado
## 1 2 3 4 5 6
```
### Dimensiones
Puede transformar un vector atómico en una matriz *n*-dimensional dándole un atributo de dimensiones con `dim`. Para hacer esto, establezca el atributo `dim` en un vector numérico de longitud *n*. R reorganizará los elementos del vector en *n* dimensiones. Cada dimensión tendrá tantas filas (o columnas, etc.) como el valor *n* del vector `dim`. Por ejemplo, puede reorganizar `dado` en una matriz de 2 × 3 (que tiene 2 filas y 3 columnas):
``` r
dim(dado) <- c(2, 3)
dado
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
```
o en una mariz de 3 × 2 (que tiene 3 filas y 2 columnas):
``` r
dim(dado) <- c(3, 2)
dado
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
```
o en hipercubo de 1 × 2 × 3 (que tiene 1 fila, 2 columnas, y 3 "rebanadas"). Esta es una estructura tridimensional, pero R necesitará mostrarla rebanada por rebanada en la pantalla bidimensional de su computadora:
``` r
dim(dado) <- c(1, 2, 3)
dado
## , , 1
##
## [,1] [,2]
## [1,] 1 2
##
## , , 2
##
## [,1] [,2]
## [1,] 3 4
##
## , , 3
##
## [,1] [,2]
## [1,] 5 6
```
R siempre usará el primer valor en `dim` para el número de filas y el segundo valor para el número de columnas. En general, las filas siempre van primero en las operaciones de R que se ocupan tanto de filas como de columnas.
Puede notar que no tiene mucho control sobre cómo R reorganiza los valores en filas y columnas. Por ejemplo, R siempre llena cada matriz por columnas, en lugar de por filas. Si desea tener más control sobre este proceso, puede usar una de las funciones auxiliares de R, `matrix` o `array`. Hacen lo mismo que cambiar el atributo `dim`, pero proporcionan argumentos adicionales para personalizar el proceso.
## Matrices
Las matrices almacenan valores en una matriz bidimensional, como una matriz de álgebra lineal. Para crear uno, primero dale a `matrix` un vector atómico para reorganizar en una matriz. Luego, defina cuántas filas debe haber en la matriz configurando el argumento `nrow` en un número. `matrix` organizará su vector de valores en una matriz con el número especificado de filas. Alternativamente, puede establecer el argumento `ncol`, que le dice a R cuántas columnas incluir en la matriz:
``` r
m <- matrix(dado, nrow = 2)
m
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
```
`matrix` llenará la matriz columna por columna por defecto, pero puedes llenar la matriz fila por fila si incluyes el argumento `byrow = TRUE`:
``` r
m <- matrix(dado, nrow = 2, byrow = TRUE)
m
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
```
`matrix` también tiene otros argumentos predeterminados que puede usar para personalizar su matriz. Puede leer sobre ellos en la página de ayuda de `matrix` (accesible por `?matrix`).
## Arreglos
La función `array` crea una matriz de n dimensiones. Por ejemplo, podría usar `array` para clasificar los valores en un cubo de tres dimensiones o un hipercubo en 4, 5 o *n* dimensiones. `array` no es tan personalizable como `matrix` y básicamente hace lo mismo que configurar el atributo `dim`. Para usar `array`, proporcione un vector atómico como primer argumento y un vector de dimensiones como segundo argumento, ahora llamado `dim`:
``` r
ar <- array(c(11:14, 21:24, 31:34), dim = c(2, 2, 3))
ar
## , , 1
##
## [,1] [,2]
## [1,] 11 13
## [2,] 12 14
##
## , , 2
##
## [,1] [,2]
## [1,] 21 23
## [2,] 22 24
##
## , , 3
##
## [,1] [,2]
## [1,] 31 33
## [2,] 32 34
```
**Ejercicio 5.3 (Hacer una Matriz)** Cree la siguiente matriz, que almacena el nombre y el palo de cada carta en una escalera real.
``` r
## [,1] [,2]
## [1,] "as" "picas"
## [2,] "rey" "picas"
## [3,] "reina" "picas"
## [4,] "jota" "picas"
## [5,] "diez" "picas"
```
*Solución.* Hay más de una forma de construir esta matriz, pero en todos los casos, deberá comenzar creando un vector de caracteres con 10 valores. Si comienza con el siguiente vector de caracteres, puede convertirlo en una matriz con cualquiera de los siguientes tres comandos:
``` r
mano1 <- c("as", "rey", "reina", "jota", "diez", "picas", "picas",
"picas", "picas", "picas")
matrix(mano1, nrow = 5)
matrix(mano1, ncol = 2)
dim(mano1) <- c(5, 2)
```
También puede comenzar con un vector de caracteres que enumere las cartas en un orden ligeramente diferente. En este caso, deberá pedirle a R que llene la matriz fila por fila en lugar de columna por columna:
``` r
mano2 <- c("as", "picas", "rey", "picas", "reina", "picas", "jota",
"picas", "diez", "picas")
matrix(mano2, nrow = 5, byrow = TRUE)
matrix(mano2, ncol = 2, byrow = TRUE)
```
## Clases
Tenga en cuenta que cambiar las dimensiones de su objeto no cambiará el tipo del objeto, pero *cambiará* el atributo `clase` del objeto:
``` r
dim(dado) <- c(2, 3)
typeof(dado)
## "double"
class(dado)
## "matrix"
```
Una matriz es un caso especial de un vector atómico. Por ejemplo, la matriz `dado` es un caso especial de vector doble. Cada elemento de la matriz sigue siendo un doble, pero los elementos se han organizado en una nueva estructura. R agregó un atributo de `clase` a `dado` cuando cambiaste sus dimensiones. Esta clase describe el nuevo formato de `dado`. Muchas funciones de R buscarán específicamente el atributo `clase` de un objeto y luego manejarán el objeto de una manera predeterminada en función del atributo.
Tenga en cuenta que el atributo `clase` de un objeto no siempre aparecerá cuando ejecute `attributes`; es posible que deba buscarlo específicamente con `class`:
``` r
attributes(dado)
## $dim
## [1] 2 3
```
Puede aplicar `class` a objetos que no tienen un atributo de `clase`. `class` devolverá un valor basado en el tipo atómico del objeto. Tenga en cuenta que la "clase" de un doble es "numérica", una desviación extraña, pero por la que estoy agradecido. Creo que la propiedad más importante de un vector doble es que contiene números, una propiedad que "numeric" hace evidente:
``` r
class("Hola")
## "character"
class(5)
## "numeric"
```
También puede usar `class` para establecer el atributo `clase` de un objeto, pero esto suele ser una mala idea. R esperará que los objetos de una clase compartan ciertas características, como atributos, que su objeto puede no poseer. Aprenderá a crear y utilizar sus propias clases en [Proyecto 3: Máquina Tragamonedas](#slots).
### Fechas y Horarios
El sistema de atributos permite que R represente más tipos de datos que solo dobles, enteros, caracteres, lógicos, complejos y sin procesar. La hora parece una cadena de caracteres cuando la visualizas, pero su tipo de datos es en realidad `"doble"`, y su clase es `"POSIXct"` `"POSIXt"` (tiene dos clases):
``` r
ahora <- Sys.time()
ahora
## "2014-03-17 12:00:00 UTC"
typeof(ahora)
## "double"
class(ahora)
## "POSIXct" "POSIXt"
```
POSIXct es un marco ampliamente utilizado para representar fechas y horas. En el marco de POSIXct, cada hora se representa por la cantidad de segundos que han pasado entre la hora y las 12:00 a. m. del 1 de enero de 1970 (en la zona Universal Time Coordinated (UTC)). Por ejemplo, el tiempo anterior ocurre 1 395 057 600 segundos después. Entonces, en el sistema POSIXct, el tiempo se guardaría como 1395057600.
R crea el objeto de tiempo construyendo un vector doble con un elemento, `1395057600`. Puede ver este vector eliminando el atributo `clase` de `ahora`, o usando la función `unclass`, que hace lo mismo:
``` r
unclass(ahora)
## 1395057600
```
R luego le da al vector doble un atributo `clase` que contiene dos clases, `"POSIXct"` y `"POSIXt"`. Este atributo alerta a las funciones de R de que están tratando con un tiempo POSIXct, para que puedan tratarlo de una manera especial. Por ejemplo, las funciones R usarán el estándar POSIXct para convertir la hora en una cadena de caracteres fácil de usar antes de mostrarla.
Puede aprovechar este sistema dando la clase `POSIXct` a objetos R aleatorios. Por ejemplo, ¿alguna vez se ha preguntado qué día era un millón de segundos después de las 12:00 a. m. del 1 de enero de 1970?
``` r
millon <- 1000000
millon
## 1e+06
class(millon) <- c("POSIXct", "POSIXt")
millon
## "1970-01-12 13:46:40 UTC"
```
12 de enero de 1970. Vaya. Un millón de segundos pasan más rápido de lo que piensas. Esta conversión funcionó bien porque la clase `POSIXct` no depende de ningún atributo adicional, pero en general, forzar la clase de un objeto es una mala idea.
Hay muchas clases diferentes de datos en R y sus paquetes, y cada día se inventan nuevas clases. Sería difícil aprender sobre cada clase, pero no es necesario. La mayoría de las clases solo son útiles en situaciones específicas. Dado que cada clase viene con su propia página de ayuda, puede esperar para aprender sobre una clase hasta que la encuentre. Sin embargo, hay una clase de datos que es tan omnipresente en R que debería conocerla junto con los tipos de datos atómicos. Esa clase es `factores`.
### Factores
Los factores son la forma en que R almacena información categórica, como el origen étnico o el color de ojos. Piense en un factor como algo así como un género; solo puede tener ciertos valores (masculino o femenino), y estos valores pueden tener su propio orden idiosincrático (damas primero). Este arreglo hace que los factores sean muy útiles para registrar los niveles de tratamiento de un estudio y otras variables categóricas.
Para hacer un factor, pase un vector atómico a la función `factor`. R recodificará los datos en el vector como enteros y almacenará los resultados en un vector entero. R también agregará un atributo `niveles` (`levels` en inglés) al entero, que contiene un conjunto de etiquetas para mostrar los valores de los factores, y un atributo `class`, que contiene la clase `factor`:
``` r
genero <- factor(c("masculino", "femenino", "femenino", "masculino"))
typeof(genero)
## "integer"
attributes(genero)
## $levels
## [1] "femenino" "masculino"
##
## $class
## [1] "factor"
```
Puedes ver exactamente cómo R almacena tu factor con `unclass`:
``` r
unclass(genero)
## [1] 2 1 1 2
## attr(,"levels")
## [1] "femenino" "masculino"
```
R usa el atributo de niveles cuando muestra el factor, como verá. R mostrará cada `1` como `femenino`, la primera etiqueta en el vector de niveles, y cada `2` como `masculino`, la segunda etiqueta. Si el factor incluyera `3`, se mostrarían como la tercera etiqueta, y así sucesivamente:
``` r
genero
## masculino femenino femenino masculino
## Levels: femenino masculino
```
Los factores facilitan la colocación de variables categóricas en un modelo estadístico porque las variables ya están codificadas como números. Sin embargo, los factores pueden resultar confusos, ya que parecen cadenas de caracteres pero se comportan como números enteros.
R a menudo intentará convertir cadenas de caracteres en factores cuando cargue y cree datos. En general, tendrá una experiencia más fluida si no permite que R haga factores hasta que los solicite. Te mostraré cómo hacer esto cuando comencemos a leer datos.
Puede convertir un factor en una cadena de caracteres con la función `as.character`. R conservará la versión de visualización del factor, no los números enteros almacenados en la memoria:
``` r
as.character(genero)
## "masculino" "femenino" "femenino" "masculino"
```
Ahora que comprende las posibilidades que brindan los vectores atómicos de R, hagamos un tipo de naipe más complicado.
**Ejercicio 5.4 (Escriba una Carta)** Muchos juegos de cartas asignan un valor numérico a cada carta. Por ejemplo, en el blackjack, cada carta con figuras vale 10 puntos, cada carta con números vale entre 2 y 10 puntos, y cada as vale 1 u 11 puntos, dependiendo de la puntuación final.
Haz un naipe virtual combinando "as", "corazón" y 1 en un vector. ¿Qué tipo de vector atómico resultará? Comprueba si tienes razón.
*Solución.* Es posible que hayas adivinado que este ejercicio no saldría bien. Cada vector atómico solo puede almacenar un tipo de datos. Como resultado, R convierte todos sus valores en cadenas de caracteres:
``` r
carta <- c("as", "corazones", 1)
carta
## "as" "corazones" "1"
```
Esto causará problemas si desea hacer operaciones matemáticas con ese valor en puntos, por ejemplo, para ver quién ganó su juego de blackjack.
::: callout-warning
**Tipos de datos en vectores**
Si intenta poner varios tipos de datos en un vector, R convertirá los elementos en un solo tipo de datos.
:::
Dado que las matrices y los arreglos son casos especiales de vectores atómicos, sufren el mismo comportamiento. Cada uno solo puede almacenar un tipo de datos.
Esto crea un par de problemas. Primero, muchos conjuntos de datos contienen múltiples tipos de datos. Los programas simples como Excel y Numbers pueden guardar múltiples tipos de datos en el mismo conjunto de datos, y debería esperar que R también pueda hacerlo. No te preocupes, puede.
En segundo lugar, la coerción es un comportamiento común en R, por lo que querrá saber cómo funciona.
## Coerción
El comportamiento de coerción de R puede parecer inconveniente, pero no es arbitrario. R siempre sigue las mismas reglas cuando obliga a los tipos de datos. Una vez que esté familiarizado con estas reglas, puede usar el comportamiento de coerción de R para hacer cosas sorprendentemente útiles.
Entonces, ¿cómo coacciona R los tipos de datos? Si una cadena de caracteres está presente en un vector atómico, R convertirá todo lo demás en el vector en cadenas de caracteres. Si un vector solo contiene lógicos y números, R convertirá los lógicos en números; cada `TRUE` se convierte en 1, y cada `FALSE` se convierte en 0, como se muestra en la Figura @fig-coercion.
```{r}
#| label: fig-coercion
#| echo: FALSE
#| fig.cap: >
#| R siempre usa las mismas reglas para obligar a los datos a un solo
#| tipo. Si hay cadenas de caracteres presentes, todo se convertirá en una
#| cadena de caracteres. De lo contrario, los lógicos se convierten en numéricos.
knitr::include_graphics("images/hopr_0301.png")
```
Este arreglo preserva la información. Es fácil mirar una cadena de caracteres y decir qué información solía contener. Por ejemplo, puede detectar fácilmente los orígenes de `"TRUE"` y `"5"`. También puede volver a transformar fácilmente un vector de 1 y 0 en `TRUE` y `FALSE`.
R usa las mismas reglas de coerción cuando intenta hacer operaciones matemáticas con valores lógicos. Entonces el siguiente código:
``` r
sum(c(TRUE, TRUE, FALSE, FALSE))
```
se convertirá:
``` r
sum(c(1, 1, 0, 0))
## 2
```
Esto significa que `sum` contará el número de `TRUE` en un vector lógico (y `mean` calculará la proporción de `TRUE`). Listo, ¿eh?
Puede pedirle explícitamente a R que convierta datos de un tipo a otro con las funciones `as`. R convertirá los datos siempre que haya una forma sensata de hacerlo:
``` r
as.character(1)
## "1"
as.logical(1)
## TRUE
as.numeric(FALSE)
## 0
```
Ahora sabe cómo R coacciona los tipos de datos, pero esto no lo ayudará a salvar una carta. Para hacer eso, deberá evitar la coerción por completo. Puedes hacer esto usando un nuevo tipo de objeto, una *lista*.
Antes de ver las listas, abordemos una pregunta que podría tener en mente.
Muchos conjuntos de datos contienen múltiples tipos de información. La incapacidad de vectores, matrices y arreglos para almacenar múltiples tipos de datos parece ser una limitación importante. Entonces, ¿por qué molestarse con ellos?
En algunos casos, usar un solo tipo de datos es una gran ventaja. Los vectores, las matrices y los arreglos hacen que sea muy fácil hacer operaciones matemáticas con grandes conjuntos de números porque R sabe que puede manipular cada valor de la misma manera. Las operaciones con vectores, matrices y arreglos también tienden a ser rápidas porque los objetos son muy fáciles de almacenar en la memoria.
En otros casos, permitir un solo tipo de datos no es una desventaja. Los vectores son la estructura de datos más común en R porque almacenan muy bien las variables. Cada valor de una variable mide la misma propiedad, por lo que no es necesario utilizar diferentes tipos de datos.
## Listas
Las listas son como vectores atómicos porque agrupan datos en un conjunto unidimensional. Sin embargo, las listas no agrupan valores individuales; las listas agrupan objetos de R, como vectores atómicos y otras listas. Por ejemplo, puede crear una lista que contenga un vector numérico de longitud 31 en su primer elemento, un vector de caracteres de longitud 1 en su segundo elemento y una nueva lista de longitud 2 en su tercer elemento. Para hacer esto, use la función `list`.
`list` crea una lista de la misma manera que `c` crea un vector. Separe cada elemento de la lista con una coma:
``` r
lista1 <- list(100:130, "R", list(TRUE, FALSE))
lista1
## [[1]]
## [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
## [27] 126 127 128 129 130
##
## [[2]]
## [1] "R"
##
## [[3]]
## [[3]][[1]]
## [1] TRUE
##
## [[3]][[2]]
## [1] FALSE
```
Dejé la notación `[1]` en la salida para que puedas ver cómo cambia para las listas. Los índices entre corchetes le indican qué elemento de la lista se está mostrando. Los índices de un solo paréntesis le indican qué subelemento de un elemento se muestra. Por ejemplo, `100` es el primer subelemento del primer elemento de la lista. `"R"` es el primer subelemento del segundo elemento. Esta notación de dos sistemas surge porque cada elemento de una lista puede ser *cualquier* objeto R, incluido un nuevo vector (o lista) con sus propios índices.
Las listas son un tipo básico de objeto en R, a la par de los vectores atómicos. Al igual que los vectores atómicos, se utilizan como bloques de construcción para crear muchos tipos más sofisticados de objetos de R.
Como puede imaginar, la estructura de las listas puede volverse bastante complicada, pero esta flexibilidad hace que las listas sean una herramienta de almacenamiento útil para todo uso en R: puede agrupar cualquier cosa con una lista.
Sin embargo, no todas las listas tienen que ser complicadas. Puede almacenar una carta de juego en una lista muy simple.
**Ejercicio 5.5 (Usar una Lista para Crear una Carta)** Use una lista para almacenar una sola carta, como el as de corazones, que tiene un valor de punto de uno. La lista debe guardar la cara de la carta, el palo y el valor del punto en elementos separados.
*Solución.* Puedes crear tu carta así. En el siguiente ejemplo, el primer elemento de la lista es un vector de caracteres (de longitud 1). El segundo elemento también es un vector de caracteres y el tercer elemento es un vector numérico:
``` r
carta <- list("as", "corazones", 1)
carta
## [[1]]
## [1] "as"
##
## [[2]]
## [1] "corazones"
##
## [[3]]
## [1] 1
```
También puede usar una lista para almacenar una baraja completa de cartas. Dado que puede guardar una sola carta de juego como una lista, puede guardar una baraja de cartas de juego como una lista de 52 sublistas (una para cada carta). Pero no nos molestemos, hay una forma mucho más limpia de hacer lo mismo. Puede usar una clase especial de lista, conocida como *data frames*.
## Data Frames
Data frames son la versión bidimensional de una lista. Son, por mucho, la estructura de almacenamiento más útil para el análisis de datos y proporcionan una forma ideal de almacenar una baraja completa de cartas. Puede pensar en un data frame como el equivalente de R a la hoja de cálculo de Excel porque almacena datos en un formato similar.
Data frames agrupan vectores en una tabla bidimensional. Cada vector se convierte en una columna en la tabla. Como resultado, cada columna de un data frame puede contener un tipo diferente de datos; pero dentro de una columna, cada celda debe tener el mismo tipo de datos, como en la Figura @fig-data-frame.
```{r}
#| label: fig-data-frame
#| echo: FALSE
#| fig.cap: >
#| Data frames almacenan datos como una secuencia de columnas. Cada
#| columna puede ser un tipo de datos diferente. Cada columna en un
#| data frame debe tener la misma longitud.
knitr::include_graphics("images/hopr_0302.png")
```
Crear un data frame a mano requiere escribir mucho, pero puede hacerlo (si lo desea) con la función `data.frame`. Proporcione a `data.frame` cualquier número de vectores, cada uno separado por una coma. Cada vector debe establecerse igual a un nombre que describa el vector. `data.frame` convertirá cada vector en una columna del nuevo data frame:
``` r
df <- data.frame(cara = c("as", "dos", "seis"),
palo = c("treboles", "treboles", "treboles"), valor = c(1, 2, 3))
df
## cara palo valor
## as treboles 1
## dos treboles 2
## seis treboles 3
```
Deberá asegurarse de que cada vector tenga la misma longitud (o se puede hacer así con las reglas de reciclaje de R; consulte la figura @fig-recycle, ya que los data frames no pueden combinar columnas de diferentes longitudes.
En el código anterior, nombré los argumentos en `data.frame` `cara`, `palo` y `valor`, pero puedes nombrar los argumentos como quieras. `data.frame` utilizará los nombres de sus argumentos para etiquetar las columnas del data frame.
::: callout-tip
**Nombres**
También puede dar nombres a una lista o vector cuando crea uno de estos objetos. Use la misma sintaxis que con `data.frame`:
`list(cara = "as", palo = "corazones", value = 1)`\
`c(cara = "as", palo = "corazones", value = "one")`
Los nombres se almacenarán en el atributo `names` del objeto.
:::
Si observa el tipo de data frame, verá que es una lista. De hecho, cada data frame es una lista con la clase `data.frame`. Puede ver qué tipos de objetos se agrupan en una lista (o data frame) con la función `str`:
``` r
typeof(df)
## "list"
class(df)
## "data.frame"
str(df)
## 'data.frame': 3 obs. of 3 variables:
## $ cara : Factor w/ 3 levels "as","seis","dos": 1 3 2
## $ palo : Factor w/ 1 level "treboles": 1 1 1
## $ valor: num 1 2 3
```
Observe que R guardó sus cadenas de caracteres como factores. ¡Te dije que a R le gustan los factores! No es un gran problema aquí, pero puede evitar este comportamiento agregando el argumento `stringsAsFactors = FALSE` a `data.frame`:
``` r
df <- data.frame(cara = c("as", "dos", "seis"),
palo = c("treboles", "treboles", "treboles"), value = c(1, 2, 3),
stringsAsFactors = FALSE)
```
Un data frame es una excelente manera de construir una baraja completa de cartas. Puede convertir cada fila del data frame en una carta de juego y cada columna en un tipo de valor, cada uno con su propio tipo de datos apropiado. El data frame se vería así:
``` r
## cara palo valor
## rey picas 13
## reina picas 12
## jota picas 11
## diez picas 10
## nueve picas 9
## ocho picas 8
## siete picas 7
## seis picas 6
## cinco picas 5
## cuatro picas 4
## tres picas 3
## dos picas 2
## as picas 1
## rey treboles 13
## reina treboles 12
## jota treboles 11
## diez treboles 10
## ... y así sucesivamente.
```
Podría crear este data frame con `data.frame`, ¡pero mire la escritura involucrada! Necesitas escribir tres vectores, cada uno con 52 elementos:
``` r
baraja <- data.frame(
cara = c("rey", "reina", "jota", "diez", "nueve", "ocho", "siete", "seis",
"cinco", "cuatro", "tres", "dos", "as", "rey", "reina", "jota", "diez",
"nueve", "ocho", "siete", "seis", "cinco", "cuatro", "tres", "dos", "as",
"rey", "reina", "jota", "diez", "nueve", "ocho", "siete", "seis", "cinco",
"cuatro", "tres", "dos", "as", "rey", "reina", "jota", "diez", "nueve",
"ocho", "siete", "seis", "cinco", "cuatro", "tres", "dos", "as"),
palo = c("picas", "picas", "picas", "picas", "picas", "picas",
"picas", "picas", "picas", "picas", "picas", "picas", "picas",
"treboles", "treboles", "treboles", "treboles", "treboles", "treboles", "treboles", "treboles",
"treboles", "treboles", "treboles", "treboles", "treboles", "diamantes", "diamantes",
"diamantes", "diamantes", "diamantes", "diamantes", "diamantes", "diamantes",
"diamantes", "diamantes", "diamantes", "diamantes", "diamantes", "corazones",
"corazones", "corazones", "corazones", "corazones", "corazones", "corazones", "corazones",
"corazones", "corazones", "corazones", "corazones", "corazones"),
valor = c(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 13, 12, 11, 10, 9, 8,
7, 6, 5, 4, 3, 2, 1, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 13, 12, 11,
10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
)
```
Debe evitar escribir grandes conjuntos de datos a mano siempre que sea posible. Escribir invita a errores tipográficos y errores. Siempre es mejor adquirir grandes conjuntos de datos como un archivo de computadora. Luego puede pedirle a R que lea el archivo y almacene el contenido como un objeto.
Creé un archivo para que lo cargues que contiene un data frame de información de naipes, así que no te preocupes por escribir el código. En su lugar, dirija su atención hacia la carga de datos en R.
## Cargar Datos {#loading}
Puede cargar el data frame `Mazo` desde el archivo [*mazo.csv*](https://bit.ly/mazocsv). Tómese un momento para descargar el archivo antes de seguir leyendo. Visite el sitio web, haga clic en "Descargar Zip" y luego descomprima y abra la carpeta que descarga su navegador web. *mazo.csv* estará dentro.
*mazo.csv* es un archivo de valores separados por comas, o CSV para abreviar. Los CSV son archivos de texto sin formato, lo que significa que puede abrirlos en un editor de texto (así como en muchos otros programas). Si abre *mazo.csv*, notará que contiene una tabla de datos similar a la siguiente tabla. Cada fila de la tabla se guarda en su propia línea y se usa una coma para separar las celdas dentro de cada fila. Cada archivo CSV comparte este formato básico:
```
"cara","palo","valor"
"rey","picas",13
"reina","picas",12
"jota","picas",11
"diez","picas",10
"nueve","picas",9
... y así sucesivamente.
```
La mayoría de las aplicaciones de ciencia de datos pueden abrir archivos de texto sin formato y exportar datos como archivos de texto sin formato. Esto hace que los archivos de texto sin formato sean una especie de lingua franca para la ciencia de datos.
Para cargar un archivo de texto sin formato en R, haga clic en el icono Import Dataset en RStudio, que se muestra en la Figura @fig-import. Luego seleccione "From text file (base)".
```{r}
#| label: fig-import
#| echo: FALSE
#| fig.cap: >
#| Puede importar datos desde archivos de texto sin formato con
#| Import Dataset de RStudio.
knitr::include_graphics("images/hopr_0303.png")
```
RStudio le pedirá que seleccione el archivo que desea importar, luego abrirá un asistente para ayudarlo a importar los datos, como en la Figura @fig-wizard. Utilice el asistente para decirle a RStudio qué nombre dar al conjunto de datos. También puede usar el asistente para decirle a RStudio qué carácter usa el conjunto de datos como separador, qué carácter usa para representar decimales (generalmente un punto en los Estados Unidos y una coma en Europa) y si el conjunto de datos viene o no con una fila de nombres de columna (conocido como *header*). Para ayudarlo, el asistente le muestra cómo se ve el archivo sin procesar, así como también cómo se verán los datos cargados según la configuración de entrada.
También puede desmarcar la casilla "Strings as factors" en el asistente. Recomiendo hacer esto. Si lo hace, R cargará todas sus cadenas de caracteres como cadenas de caracteres. Si no lo hace, R los convertirá en factores.
```{r}
#| label: fig-wizard
#| echo: FALSE
#| fig.cap: >
#| Asistente de importación de RStudio.
knitr::include_graphics("images/hopr_0304.png")
```
Una vez que todo se vea bien, haga clic en Import. RStudio leerá los datos y los guardará en un data frame. RStudio también abrirá un visor de datos, para que pueda ver sus nuevos datos en un formato de hoja de cálculo. Esta es una buena manera de verificar que todo salió como se esperaba. Si todo funcionó bien, su archivo debería aparecer en una pestaña View de RStudio, como se ve en la Figura @fig-view. Puede examinar el data frame en la consola con *`head(mazo)`*
::: callout-tip
**Datos en Línea**
Puede cargar un archivo de texto sin formato directamente desde Internet haciendo click en Import Dataset \> From Text (readr) y copiando la url del archivo en la casilla "File/URL" del asistente de importación de RStudio. Para poder utlizar esta opción debera instalar el paquete readr.
:::
```{r}
#| label: fig-view
#| echo: FALSE
#| fig.cap: >
#| Cuando importa un conjunto de datos, RStudio guardará los datos en
#| un data frame y luego mostrará el data frame en una pestaña View.
#| Puede abrir cualquier data frame en una pestaña View en cualquier momento
#| con la función View.
knitr::include_graphics("images/hopr_0305.png")
```
Ahora es tu turno. Descargue *mazo.csv* e impórtelo a RStudio. Asegúrese de guardar la salida en un objeto de R llamado `mazo`: lo usará en los próximos capítulos. Si todo va correctamente, las primeras líneas de su data frame deberían verse así:
``` r
head(mazo)
## cara palo valor
## rey picas 13
## reina picas 12
## jota picas 11
## diez picas 10
## nueve picas 9
## ocho picas 8
```
::: callout-note
`head` y `tail` son dos funciones que proporcionan una manera fácil de echar un vistazo a grandes conjuntos de datos. `head` devolverá solo las primeras seis filas del conjunto de datos, y `tail` devolverá solo las últimas seis filas. Para ver un número diferente de filas, dé a `head` o `tail` un segundo argumento, el número de filas que le gustaría ver, por ejemplo, `head (mazo, 10)`.
:::
R puede abrir muchos tipos de archivos, no solo CSV. Visite [Cargar y Guardar Datos en R](#dataio) para obtener información sobre cómo abrir otros tipos comunes de archivos en R.
## Guardar Datos
Antes de continuar, guardemos una copia de `mazo` como un nuevo archivo *.csv*. De esa manera, puede enviarlo por correo electrónico a un colega, almacenarlo en una memoria USB o abrirlo en un programa diferente. Puede guardar cualquier data frame en R en un archivo *.csv* con el comando `write.csv`. Para guardar `mazo`, ejecute:
``` r
write.csv(mazo, file = "cartas.csv", row.names = FALSE)
```
R convertirá su data frame en un archivo de texto sin formato con el formato de valores separados por comas y guardará el archivo en su directorio de trabajo. Para ver dónde está su directorio de trabajo, ejecute *`getwd()`*. Para cambiar la ubicación de su directorio de trabajo, visite Session \> Set Working Directory \> Choose Directory en la barra de menú de RStudio.
Puede personalizar el proceso de guardado con el amplio conjunto de argumentos opcionales de `write.csv` (consulte `?write.csv` para obtener más detalles). Sin embargo, hay tres argumentos que debería usar *cada* vez que ejecute `write.csv`.
Primero, debe darle a `write.csv` el nombre del data frame que desea guardar. A continuación, debe proporcionar un nombre de archivo para darle a su archivo. R tomará este nombre literalmente, así que asegúrese de proporcionar una extensión.
Finalmente, debe agregar el argumento `row.names = FALSE`. Esto evitará que R agregue una columna de números al comienzo de su data frame. Estos números identificarán sus filas del 1 al 52, pero es poco probable que cualquier programa en el que abra *cartas.csv* comprenda el sistema de nombres de fila. Lo más probable es que el programa asuma que los nombres de las filas son la primera columna de datos en su data frame. De hecho, esto es exactamente lo que asumirá R si vuelve a abrir *cartas.csv*. Si guarda y abre *cartas.csv* varias veces en R, notará que se forman columnas duplicadas de números de fila al comienzo de su data frame. No puedo explicar por qué R hace esto, pero puedo explicar cómo evitarlo: use `row.names = FALSE` siempre que guarde datos con `write.csv`.
Para obtener más detalles sobre cómo guardar archivos, incluido cómo comprimir archivos guardados y cómo guardar archivos en otros formatos, consulte [Cargar y Guardar Datos en R](#dataio).
Buen trabajo. Ahora tiene una baraja de cartas virtual con la que trabajar. Tómese un respiro y, cuando regrese, comenzaremos a escribir algunas funciones para usar en su mazo.
## Resumen
Puede guardar datos en R con cinco objetos diferentes, que le permiten almacenar diferentes tipos de valores en diferentes tipos de relaciones, como en la Figura @fig-structures. De estos objetos, los data frame son, por mucho, los más útiles para la ciencia de datos. Los data frame almacenan una de las formas de datos más comunes utilizadas en la ciencia de datos, los datos tabulares.
```{r}
#| label: fig-structures
#| echo: FALSE
#| fig.cap: >
#| Las estructuras de datos más comunes de R son vectores, matrices, arreglos,
#| listas y marcos de datos.
knitr::include_graphics("images/hopr_0306.png")
```
Puede cargar datos tabulares en un data frame con el botón Import Dataset de RStudio, siempre que los datos se guarden como un archivo de texto sin formato. Este requisito no es tan limitante como parece. La mayoría de los programas de software pueden exportar datos como un archivo de texto sin formato. Entonces, si tiene un archivo de Excel (por ejemplo), puede abrir el archivo en Excel y exportar los datos como CSV para usar con R. De hecho, abrir un archivo en su programa original es una buena práctica. Los archivos de Excel usan metadatos, como hojas y fórmulas, que ayudan a Excel a trabajar con el archivo. R puede intentar extraer datos sin procesar del archivo, pero no será tan bueno para hacerlo como lo es Microsoft Excel. Ningún programa es mejor para convertir archivos de Excel que Excel. Del mismo modo, ningún programa es mejor para convertir archivos SAS Xport que SAS, y así sucesivamente.
Sin embargo, es posible que se encuentre con un archivo específico del programa, pero no con el programa que lo creó. No querría comprar una licencia SAS de varios miles de dólares solo para abrir un archivo SAS. Afortunadamente, R *puede* abrir muchos tipos de archivos, incluidos archivos de otros programas y bases de datos. R incluso tiene sus propios formatos específicos del programa que pueden ayudarlo a ahorrar memoria y tiempo si sabe que trabajará completamente en R. Si desea obtener más información sobre todas sus opciones para cargar y guardar datos en R, consulte [Cargar y Guardar Datos en R](#dataio).
[Notación de R](#notation) se basará en las habilidades que aprendió en este capítulo. Aquí, aprendió cómo almacenar datos en R. En [Notación de R](#notation), aprenderá cómo acceder a los valores una vez que se han almacenado. También escribirá dos funciones que le permitirán comenzar a usar su mazo, una función para barajar y una función para repartir.