-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathr.tex
1441 lines (1151 loc) · 50.4 KB
/
r.tex
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
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%Autor: miguev
%miguev: 24
\chapter{GNU R}
\label{r.tex}
\index{R}
\index{GNU R}
\section{Introducción}
%%%%%% Traducido de la web de R en http://www.r-project.org
{\sf R} es a la vez un entorno y un lenguaje de programación para
realizar cálculos y gráficos estadísticos. Es un proyecto GNU similiar
al sistema {\sf S} desarrollado en Bell Laboratories (formalmente
AT\&T, ahora Lucent Technologies) por John Chambers y sus colegas.
{\sf R} puede considerarse como una implementación diferente de {\sf
S}. Hay diferencias importantes entre ambos, pero mucho código escrito
para el sistema {\sf S} puede ejecutarse en {\sf R} sin modificarlo.
{\sf R} proporciona una amplia variedad de técnicas gráficas y
estadísticas (regresiones lineales y no lineales, tests estadísticos
clásicos, análisis de series temporales, clasifiaciones, clustering,
etc.) y además es muy extensible. El lenguaje {\sf S} suele ser
utilizado para la investigación en metodología estadística, y {\sf R}
proporciona una alternativa de código abierto para esta actividad.
Uno de los puntos fuertes de {\sf R} es la facilidad con la que se
pueden producir gráficas de buen diseño y calidad de imprenta,
incluyendo símbolos y fórmulas matemáticas donde sean necesarias.
Aunque {\sf R} pone un gran cuidado en las opciones por defecto para
el diseño de las gráficas, el usuario puede tener control total sobre
éstas.
{\sf R} es Software Libre, disponible bajo los términos de la GNU
General Public License de la Free Software Foundation, en forma de
código fuente. Se puede compilar y ejecutar en una amplia variedad de
plataformas UNIX (incluyendo Linux y FreeBSD), MacOS y Windows
9x/NT/2000.
El código fuente de {\sf R} se puede descargar del sitio web
del proyecto {\sf R} ({\tt http://www.r-project.org}), así como su
documentación. Además de la documentación oficial (en inglés) existen
otros documentos {\em contribuidos} entre los que se encuentra la
traducción al español de ``An Introduction to R'' y ``Gráficos
Estadísticos con R''. \index{R!documentación} Estos y más manuales se
encuentran en el CRAN (Comprehensive R Archive Network), concretamente
en {\tt http://cran.r-project.org/other-docs.html}
%%%%%%
\section{El entorno R}
\index{R!entorno}
{\sf R} es un conjunto integrado de utilidades para manipulación,
cálculo y representación de datos. Decimos que {\sf R} es un
{\em entorno} porque es un sistema diseñado para ser completamente
coherente. El entorno de {\sf R} proporciona facilidades para
manipulación y almacenamiento de datos, operaciones con variables
indexadas (como vectores y matrices), análisis y representación de
datos, un lenguaje de programación bien desarrollado (con todo lo que
cabe esperar de un lenguaje de programación) y una amplia colección
integrada y coherente de utilidades para análisis de datos.
Aunque mucha gente utiliza {\sf R} como un sistema estadístico, sus
autores prefieren considerarlo como ``un entorno en el que se han
implementado muchas técnicas estadísticas, clásicas y modernas''. La
mayoría de la estadística clásica y muchas de los últimos métodos
están disponibles en {\sf R}, aunque posiblemente tendrás que buscar
un rato para encontrarlas.
La forma de trabajar con {\sf R} es distinta a la de otros programas
como {\tt SPSS}. En {\sf R}, un análisis estadístico se realiza en una
serie de pasos, con unos resultados intermedios que se van almacenando
en objetos, para ser observados o analizados posteriormente,
produciendo unas salidas mínimas. En {\tt SPSS} se obtendría de modo
inmediato una salida copiosa para cualquier análisis. Esto puede
parecer a primera vista una terrible incomodidad, pero si tuviéramos
que trabajar en una máquina poco potente rápidamente nos daríamos
cuenta de que puede resultar muy ventajosa la sencillez del entorno de
{\sf R} (un entorno de comandos) y la posibilidad de ver en cada
momento exactamente lo que se necesita, sin excesos que desperdicien
recursos del sistema.
Aún así, la mejor manera de trabajar con R es en un entorno gráfico,
con un sistema de ventanas como X-Window, de forma que puedas ver las
gráficas en el momento de generarlas.
Veamos cómo se trabaja con {\sf R} usándolo. En primer lugar conviene
crear un directorio y entrar en él antes de comenzar una sesión con
{\sf R}, que en éste almacena siempre en el directorio donde se
ejecutan unos ficheros donde almacena los objetos, datos, funciones y
comandos ejecutados. Esto puede sernos muy útil en trabajos largos,
podemos interrumpir la sesión con {\sf R} en cualquier momento y
recuperarla luego donde mismo la dejamos.
Hemos considerado a lo largo de este curso que el símbolo del sistema
Linux/UNIX es {\tt \$}. Vamos a considerar ahora que el símbolo del
prompt {\sf R} es {\tt $>$}. \index{R!prompt} Abre un emulador de
terminal dentro del entorno gráfico y ejecuta los siguientes comandos:
\begin{verbatim}
$ mkdir sesion_R
$ cd sesion_R
$ R
R : Copyright 2002, The R Development Core Team
Version 1.5.1 (2002-06-17)
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type `license()' or `licence()' for distribution details.
R is a collaborative project with many contributors.
Type `contributors()' for more information.
Type `demo()' for some demos, `help()' for on-line help, or
`help.start()' for a HTML browser interface to help.
Type `q()' to quit R.
>
\end{verbatim}
El prompt de {\sf R} indica el entorno que está esperando tus órdenes
para ejecutarlas. Para salir del entorno de {\sf R} puedes utilizar la
función {\tt q()} o pulsar {\tt C-d}, entonces {\sf R} te preguntará
si deseas guardar el {\em espacio de trabajo}, que es toda la
información sobre la sesión que quieres cerrar:
\index{R!sesiones}
\begin{verbatim}
> q()
Save workspace image? [y/n/c]:
\end{verbatim}
Para salir guardando la sesión pulsa {\tt y}, para salir sin guardarla
pulsa {\tt n} y para para cancelar la salida pulsa {\tt c}. Si guardas
la sesión al salir quedará almacenada en el directorio en el que
ejecutaste {\tt R}, y será automáticamente recuperada la próxima vez
que ejecutes {\tt R} dentro del directorio en cuestión.
{\sf R} dispone de un sistema de ayuda similar a las páginas de manual
de Linux/UNIX. Cuando necesites información sobre una función, por
ejemplo {\tt solve}, ejecuta la función {\tt help()} pasándole como
parámetro el nombre de la función que quieras consultar. También existe
una forma más corta: {\tt ?función}:
\index{R!ayuda}
\index{R!help@{\tt help()}}
\begin{verbatim}
> help (solve)
> ?solve
\end{verbatim}
Normalmente puedes ver la documentación también en el navegador
web. Si ejecutas {\tt help.start()} debería abrirse una ventana de
navegador con la documentación en formato HTML por la cual puedes
navegar para buscar lo que necesites.
Otra forma muy interesante de buscar ayuda dentro del entorno de {\sf
R} es pasarle una palabra a la función {\tt help.search()}. Por
ejemplo, para buscar una función que resuelva sistemas de ecuaciones
puedes empezar por buscar la palabra {\tt solve}.
\index{R!búsqueda}
\index{R!help.search@{\tt help.search()}}
\begin{verbatim}
> help.search ("solve")
Help files with alias or title matching `solve',
type `help(FOO, package = PKG)' to inspect entry `FOO(PKG) TITLE':
backsolve(base) Solve an Upper or Lower Triangular System
qr(base) The QR Decomposition of a Matrix
solve(base) Solve a System of Equations
\end{verbatim}
De un primer golpe ya sabes que el paquete {\tt base} de {\sf R}
tiene funciones para resolver sistemas triangulares (superiores o
inferiores), descomponer matrices en la forma QR y resolver sistemas
de ecuaciones (cualesquiera).
{\sf R} proporciona algunas demostraciones sobre sus capacidades.
Para ir abriendo el apetito ejecuta la funciones que muestran las
demostraciones con gráficos e imágenes:
\begin{verbatim}
> demo (graphics)
> demo (images)
\end{verbatim}
%\begin{figure}[hbtp]
%\centering\includegraphics[width=\textwidth]{imagenes/r_demos.eps}
%\index{R!demos}
%Demostraciones sobre gráficos e imágenes
%\end{figure}
\begin{figura}{r_demos}{1}
\index{R!demos}
\caption{Demostraciones sobre gráficos e imágenes}
\end{figura}
\section{El lenguaje {\sf R}}
\index{R!lenguaje}
{\sf R} es también lenguaje de programación en toda regla, con el que
puedes escribir programas que procesen ficheros de datos y generen
análisis y representaciones de los datos.
Al igual que la mayoría de lenguajes basados en UNIX, el lenguaje de
{\sf R} distingue entre mayúsculas y minúsculas. Esto es, {\tt esto} y
{\tt Esto} son símbolos distintos y pueden referirse a variables
distintas. En {\sf R} los nombres de variables pueden tener letras y
números (como en casi cualquier lenguaje), aunque {\bf no} pueden
tener el subrayado ({\tt \_}), pero en su lugar sí pueden tener el
punto. De hecho se suele utilizar el punto para separar palabras
en los nombres de las variables en {\sf R}, por ejemplo {\tt
hoja.de.datos}.
\index{R!órdenes}
\index{R!comandos}
Las órdenes (o comandos) elementales son expresiones o asignaciones.
Si ejecutas una expresión como comando ésta se evalúa y se imprime,
pero su valor se pierde. En una asignación la expresión se evalúa y su
valor se almacena en la varbiable, pero no se imprime.
Los comandos se separan con el caracter de punto y coma ({\tt ;}) o
simplemente con una salto de línea. Puedes agrupar una serie de
comandos encerrándolos entre llaves, de esta forma puedes definir
funciones como veremos más adelante. También puedes poner comantarios,
\index{R!comentarios} casi donde quieras\footnote{No puedes meter un
comentario dentro de una cadena de caracteres (formaría parte de la
cadena), ni en medio de la lista de argumentos en la definición de una
función}, poniendo una almohadilla ({\tt \#}) y todo lo que la siga
hasta el final de línea será obviado por el intérprete de {\sf R}.
Si dejas un comando a medias {\sf R} se dará cuenta, y en lugar de
mostrarte el prompt $>$ te mostará {\tt +} para avisarte de que está
esperando por el final del comando.
Otra característica interesante de {\sf R} (al menos en plataformas
Linux/UNIX) es la posibilidad de editar la línea de comandos.
Esto incluye el típico historial de comandos, que te permite
repetir los comandos sin tener que volver a teclearlos. Tan solo
utiliza los cursores arriba y abajo para recuperar los comandos que
hayas tecleado. \index{R!historial} Además este historial de comando
queda almacenado en la sesión cuando sales del entorno {\sf R},
concretamente en un fichero {\tt .Rhistory} en el directorio donde
ejecutaste en entorno {\sf R}.
Pero si necesitas usar una serie un poco larga de comandos seguramente
te canses de tener que darle a los cursores. Para estos casos lo que
necesitas es un script en el que escribes los comandos a modo de
programa. Luego para ejecutar los comandos escritos en él utilizas la
función {\tt source ()} del entorno pasándole el nombre del fichero
donde escribiste los comandos:
\index{R!leer comandos de un fichero}
\index{R!source@{\tt source()}}
\begin{verbatim}
> source ("script.R")
\end{verbatim}
Del mismo modo que puedes tomar la entrada de un fichero también
puedes redireccionar la salida hacia otro fichero, con la función {\tt
sink()}. Para almacenar la salida en el fichero {\tt salida.txt}
ejecuta el comando:
\index{R!volcar en un fichero}
\index{R!sink@{\tt sink()}}
\begin{verbatim}
> sink ("salida.txt")
\end{verbatim}
Para devolver la salida al intérprete utiliza la misma función {\tt
sink ()} pero sin pasarle ningún parámetro. En el fichero {\tt
iodemo.R} tienes un ejemplo de esto.
\begin{ejemplo}{iodemo.R}{Uso de {\tt sink()}}
Este script lee una tabla que está almacenada en un fichero de texto
llano ({\tt muestra.dat}, que usaremos para los ejemplos) y extrae dos
variables de ella. Para ambas variables muestra un breve resumen
estadístico, pero guarda uno en el fichero {\tt salida.txt} y el otro
lo muestra en el entorno {\sf R}.
\end{ejemplo}
Entra en el directorio donde tengas el fichero y ejecuta en el entorno
{\sf R}
\begin{verbatim}
> source ("iodemo.R")
\end{verbatim}
\section{Vectores}
\index{R!vectores}
{\sf R} realiza las operaciones sobre las llamadas {\em estructuras de
datos}, de las cuales la más simple es el vector numérico. Para crear
un vector con los 5 primeros números enteros positivos utilizamos la
función {\tt c()} que combina los objetos recibidos para formas un
vector:
\begin{verbatim}
> x <- c (1, 2, 3, 4, 5)
> x
[1] 1 2 3 4 5
\end{verbatim}
\index{R!asignación, operador de}
En efecto, el operador de asignación no se parece para nada a un signo
de igualdad. De hecho es una flecha, que está indicando que el valor
de lo que hay a su derecha debe asignarse a lo que hay a su izquierda.
Si le das la vuelta a la flecha funciona al revés:
\begin{verbatim}
> c (6, 7, 8, 9, 10) -> y
> y
[1] 6 7 8 9 10
\end{verbatim}
Cuando ejecutas el nombre de un objeto como comando, {\sf R}
interpreta que deseas ver su contenido y entonces ejecuta la función
{\tt print()} sobre el objeto en cuestión. Esto funciona sólo cuando
estás dentro del entorno {\sf R} y tecleas el nombre del objeto.
\index{R!print@{\tt print()}}
Cuando quieras imprimir el objeto desde un fichero de comandos (como
hacemos en {\tt iodemo.R}) has de utilizar la función {\tt print()}.
Dado que la función {\tt c()} combina objetos para formar vectores,
también puede combinar varios vectores para formar un nuevo vector
que es el resultado de concatenar los anteriores:
\begin{verbatim}
> z <- c (x, y)
> z
[1] 1 2 3 4 5 6 7 8 9 10
\end{verbatim}
Las operaciones usuales entre vectores se definen ``elemento a
elemento'':
\index{R!vectores!operaciones elementales}
\begin{verbatim}
> x + 2
[1] 3 4 5 6 7
> 2 * x
[1] 2 4 6 8 10
> x + y
[1] 7 9 11 13 15
> x - y
[1] -5 -5 -5 -5 -5
> x * y
[1] 6 14 24 36 50
> x / y
[1] 0.1666667 0.2857143 0.3750000 0.4444444 0.5000000
> y / x
[1] 6.000000 3.500000 2.666667 2.250000 2.000000
> x ^ y
[1] 1 128 6561 262144 9765625
> y ^ x
[1] 6 49 512 6561 100000
\end{verbatim}
Pero entonces ¿cómo se multiplican escalarmente dos vectores? Para
esto hay una función llamada {\tt crossprod}, que permite multiplicar
dos vectores (o matrices). El operador \verb|%*%| es una forma
abreviada de este producto. Formalmente {\tt crossprod(x,y)} es
equivalente a {\tt t(x) \%*\% y}, pero más rápido. La función {\tt
t()} es la trasposición de matrices:
\index{R!vectores!producto escalar}
\begin{verbatim}
> x
[1] 1 2 3 4
> y
[1] 4 5 6 7
> crossprod(x,y)
[,1]
[1,] 60
> x %*% y
[,1]
[1,] 60
\end{verbatim}
Además de para guardar datos, los vectores suelen usarse para definir
series o secuencias. Para definir una secuencia de números enteros
consecutivos basta con poner el primer y el último separados por un
caracter de dos puntos:
\index{R!vectores!secuencias}
\begin{verbatim}
> x <- 1:10
> x
[1] 1 2 3 4 5 6 7 8 9 10
\end{verbatim}
Pero para generar secuencias la mejor manera es utilizar la
función {\tt seq()}. Si le pasas tres valores numéricos le estarás
especificando el primer y el último elemento de la secuencia, y la
diferencia que debe haber entre cada dos elementos consecutivos:
\begin{verbatim}
> y <- seq (-1, 1, .2)
> y
[1] -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0
\end{verbatim}
Para replicar un objeto varias veces, por ejemplo para generar una
secuencia periódica, utiliza la función {\tt rep()} pasándole el
objeto y el número de veces que quieres replicarlo:
\begin{verbatim}
> z <- rep (seq (-1, 1, 1), 5)
> z
[1] -1 0 1 -1 0 1 -1 0 1 -1 0 1 -1 0 1
\end{verbatim}
Además de vectores numéricos, {\sf R} permite operar con vectores {\em
lógicos}. Los valores válidos para los elementos de los vectores
\index{R!vectores!vectores lógicos}
lógicos son los de la {\em lógica triestada}:
\index{lógica triestada}
{\tt TRUE}, {\tt FALSE} y {\tt NA} (``Not Available'', no disponible).
Los operadores lógicos para manejar estos valores son {\tt \&} para
``and'', {\tt |} para ``or'' y {\tt !} para ``not''.
Una forma de generar un vector de valores lógicos es efectuar una
comparación entre un vector numérico y un valor numérico:
\begin{verbatim}
> z <- rep (seq (-1, 1, 1), 3)
> z
[1] -1 0 1 -1 0 1 -1 0 1
> z > 0
[1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE
\end{verbatim}
Al contrario que en la mayoría de lenguajes de programación, en {\sf
R} los vectores se indexan comenzando por $1$. Para acceder a un
elemento de un vector utiliza la notación usual de los corchetes.
También puedes acceder a un subconjunto del vector especificando como
índice un vector con las posiciones de los elemenos:
\index{R!vectores!índices}
\index{R!vectores!subíndices}
\index{R!vectores!indixado}
\begin{verbatim}
> x <- 1:10
> x
[1] 1 2 3 4 5 6 7 8 9 10
> x[2:5]
[1] 2 3 4 5
> x[8:2]
[1] 8 7 6 5 4 3 2
\end{verbatim}
También puedes acceder a un subconjunto de un vector utilizando un
vector lógico:
\begin{verbatim}
> x[x > 4]
[1] 5 6 7 8 9 10
\end{verbatim}
Incluso puedes indexar un vector no palabras, poniendo nombres a las
posiciones dentro del vector mediante la función {\tt names()}. Luego
puedes acceder a los elementos mediante los nombres de las posiciones:
\index{R!vectores!nombres}
\index{R!vectores!names@{\tt names()}}
\begin{verbatim}
fruta = c (5, 10, 1, 20)
> fruta <- c (5, 10, 1, 20)
> names (fruta) <- c ("naranja", "plátano", "manzana", "ñame")
> fruta[c ("manzana", "naranja")]
manzana naranja
1 5
> fruta
naranja plátano manzana ñame
5 10 1 20
\end{verbatim}
\section{Arrays y matrices}
\index{R!arrays}
\index{R!matrices}
Un {\em array}\footnote{a veces traducido por ``arreglo''}
\index{arreglo} es una variable indexada multidimensional. Un vector
es un array unidimensional y una matriz es un array bidimensional.
{\sf R} proporciona un buen manejo de arrays, sobretodo para matrices.
La dimensión de un array es un vector cuya longitud es la dimesión del
array, y cada uno de sus elementos es la ``longitud'' de cada
dimensión en el array. Por ejemplo, un array con dimesión $(3,5,100)$
sería como un cubo de $1500$ elementos con $3$ celdas de largo, $5$ de
ancho y $100$ de alto.
\index{R!arrays!dimensión}
En la mayoría de lenguajes los elementos de un array se almacenan
``por filas'', lo que significa que el índice que avanza más rápido es
el último. Sin embargo, en {\sf R} la ordenación se hace al estilo de
FORTRAN, ordenando los elementos ``por columnas'', lo que significa
que el índice que avanza más rápido es el primero.
Es importante tener esto en cuenta porque a la hora de crear una
matriz hay que proporcionar los elementos agrupados por columnas, no
por filas. Por ejemplo:
\index{R!arrays!por filas}
\index{R!arrays!por columnas}
\begin{verbatim}
> a <- array (c (1:3,-3:-1), dim = c (3,2))
> a
[,1] [,2]
[1,] 1 -3
[2,] 2 -2
[3,] 3 -1
\end{verbatim}
Para acceder a los elementos de una matriz (o array) ponemos los
subíndices entre corchetes y separados por comas. Si omitimos el
subíndice de las filas (el primero) obtenemos la columna señalada por
el segundo subíndice, y análogamente obtenemos las filas omitiendo el
segundo suníndice.
\index{R!arrays!índices}
\index{R!arrays!subíndices}
\index{R!arrays!indexado}
\begin{verbatim}
> a[1,2]
[1] -3
> a[,2]
[1] -3 -2 -1
> a[1,]
[1] 1 -3
\end{verbatim}
De la misma forma que podemos extraer elementos, filas o columnas de
una matriz también podemos asignarles valores:
\begin{verbatim}
> a[,2] <- 3:5
> a[,2]
[1] 3 4 5
> a
[,1] [,2]
[1,] 1 3
[2,] 2 4
[3,] 3 5
\end{verbatim}
Para multiplicar matrices (o arrays en general) utiliza el operador
\verb|%*%| que vimos antes:
\index{R!arrays!producto}
\index{R!matrices!multiplicar}
\begin{verbatim}
> a
[,1] [,2]
[1,] 1 3
[2,] 2 4
[3,] 3 5
> b = array (1:2, 2:1, dim = c (2,2))
> b
[,1] [,2]
[1,] 1 1
[2,] 2 2
> a %*% b
[,1] [,2]
[1,] 7 7
[2,] 10 10
[3,] 13 13
\end{verbatim}
Vimos antes que si multiplicamos dos vectores {\tt x} y {\tt y} (de
igual longitud) utilizando el operador {\tt \%*\%} el resultado es el
producto escalar de los vectores. En realidad la operación {\tt x
\%*\% y} es ambigua, porque podría significar $x' x$ o $x x'$
(considerando $x$ un vector columna). En estos casos de ambigûedad se
considera implícitamente que la interpretación deseada es aquella de
la que resulte la matriz más paqueña, por lo que se obtiene el
producto escalar $x' x$.
Para calcular la matriz $x x'$ puedes utilizar las funciones {\tt
cbind()} y {\tt rbind()}, ya que éstas siempre devuelven matrices. Las
funciones {\tt cbind} y {\tt rbind} toman una serie de vectores o
números y los agrupan por columnas o filas en una matriz.
\index{R!matrices!cbind@{\tt cbind()}}
\index{R!matrices!rbind@{\tt rbind()}}
\begin{verbatim}
> x
[1] 1 2 3 4
> y
[1] 4 5 6 7
> x %*% y
[,1]
[1,] 60
> cbind(x,y)
x y
[1,] 1 4
[2,] 2 5
[3,] 3 6
[4,] 4 7
> rbind(x,y)
[,1] [,2] [,3] [,4]
x 1 2 3 4
y 4 5 6 7
> cbind(x) %*% rbind(y)
[,1] [,2] [,3] [,4]
[1,] 4 5 6 7
[2,] 8 10 12 14
[3,] 12 15 18 21
[4,] 16 20 24 28
\end{verbatim}
\section{Factores: clasificación de datos}
\index{R!factores}
\index{R!clasificación de datos}
Un {\em factor} es un vector que utilizamos para especificar una
clasificación discreta (agrupamiento) de los componentes de otros
vectores del mismo tamaño. Para entender lo que son los factores nada
mejor que un ejemplo claro y sencillo. En el entorno {\sf R} y ejecuta
lo siguiente:
\begin{verbatim}
> edad <- c (13, 16, 15, 17, 17, 18, 16, 16, 15, 16)
> sexo <- c ("hombre", "hombre", "mujer", "hombre", "mujer", "mujer",
+ "hombre", "mujer", "hombre", "mujer")
> edad
[1] 13 16 15 17 17 18 16 16 15 16
> sexo
[1] "hombre" "hombre" "mujer" "hombre" "mujer" "mujer" "hombre"
[9] "mujer" "hombre" "mujer"
\end{verbatim}
Ahora tienes una variable {\tt edad} que contiene las edades de 10
personas, y una variable {\tt sexo} que define el sexo de cada una
de las 10 personas anteriores (en el mismo orden) y que toma
únicamente los valores \verb|"hombre"| y \verb|"mujer"|. Vamos a
calcular la media y la varianza muestrales de la edad de estas
personas clasificándolas según el sexo, i.e. la edad media de los
hombres por un lado y la de las mujeres por otro.
Necesitamos separar (agrupar) los elementos del vector {\tt edad}
según los valores que toma el vector {\tt sexo}. Para esto utilizamos
un factor. El factor en realidad es como el vector original, pero
tiene un atributo añadido llamado {\tt levels} (niveles) que son los
distintos valores que toman los elementos del vector original. En
el caso del vector {\tt sexo} los niveles son \verb|"hombre"| y
\verb|"mujer"|. La función {\tt levels} devuelve la lista de niveles
que tenga el factor que le pases como parámetro.
\begin{verbatim}
> sexo.factor = factor (sexo)
> sexo.factor
[1] hombre hombre mujer hombre mujer mujer hombre mujer hombre
Levels: hombre mujer
> levels (sexo.factor)
[1] "hombre" "mujer"
\end{verbatim}
Ahora queremos aplicar unas funciones, en este caso {\tt mean()} y
{\tt var()}, a un vector de datos de manera que los datos sean
separados según un factor. La función apropiada para esta tarea es
{\tt tapply}, y se usa del siguiente modo:
\index{R!tapply@{\tt tapply()}}
\begin{verbatim}
> tapply (edad, sexo.factor, mean)
hombre mujer
15.4 16.4
> tapply (edad, sexo.factor, var)
hombre mujer
2.3 1.3
\end{verbatim}
Así obtenemos que dentro de esta muestra de 10 personas, la edad media
de los hombres es $15.4$ y la de las mujeres $16.4$. Volveremos sobre
los factores más adelante, así que asegúrate de entender al menos este
uso de los mismos. Para mayores detalles consulta la ayuda de {\sf R}.
\section{Listas}
\index{R!listas}
En un array todos los elementos deben ser del mismo tipo, i.e. no
puede ser que un array contenga a la vez números y palabras. Sin
embargo la mayoría de muestras contienen datos de diferentes tipos:
números, palabras, valores lógicos, intervalos, etc.
Una {\em lista} en {\sf R} es una colección ordenada de objetos de
cualquier tipo. Es como un vector, pero con la diferencia de que sus
elementos pueden ser de distintos tipos.
Los elementos de una lista están siempre numerados por un subíndice y
puedes referirte a ellos como con un vector, pero usando corquetes
dobles. Así si {\tt L} es una lista {\tt L[[1]]} es su primer
elemento. Pero también, al igual que en los vectores, puedes indexar
los elementos de una lista dándoles nombres. En caso de nombrar los
elementos de una lista hay una forma más cómoda de referirse a ellos:
en lugar de {\tt L[["nombre"]]} puedes usar {\tt L\$nombre}.
\index{R!listas!índices}
\index{R!listas!nombres}
\begin{verbatim}
> L = list (nombre = "Pepe", esposa = "Pepa", hijos = 3,
+ edades.hijos = c (34,6,12))
> L
$nombre
[1] "Pepe"
$esposa
[1] "Pepa"
$hijos
[1] 3
$edades.hijos
[1] 34 6 12
> L[["nombre"]]
[1] "Pepe"
> L$nombre
[1] "Pepe"
\end{verbatim}
Para concatenar listas recuerda que la función {\tt c()} sirve para
ello.
\section{Hojas de datos}
\index{R!tablas}
\index{R!data frame}
\index{R!frame}
\index{R!hojas de datos}
Una ``hoja de datos'' (en inglés ``data frame'') es básicamente una
lista de vectores, con algunas restricciones. Los vectores de palabras
son convertidos en factores.
Piensa en una hoja de datos como su nombre sugiere: una hoja o tabla
en la que tienes varios datos sobre varios individuos. Las columnas de
la hoja de datos son los vectores que la format, y cada fila es una
lista.
En el fichero {\tt muestra.dat} tienes una hoja de datos preparada
para ser leida con la función {\tt read.table()}. La primera fila son
los nombres de los vectores columna, y luego cada línea del fichero
introduce una lista de valores, un valor para cada vector. Para
entender esto con claridad lee la tabla del fichero {\tt muestra.dat}
y mantenla en una variable:
\index{R!hojas de datos!leer desde fichero}
\index{R!read.table@{\tt read.table()}}
\begin{verbatim}
> hoja.de.datos = read.table ("muestra.dat")
> names (hoja.de.datos)
[1] "Sexo" "Edad" "Habitat" "Ingresos" "Lectura" "TV"
\end{verbatim}
Esta tabla contiene los datos (ficticios) de 50 jóvenes: su sexo, su
edad, su hábidat, sus ingresos familiares (en miles de pesetas
mensuales), el número de libros leidos anualmente y sus horas de
televisión diarias.
Normalmente para acceder al vector {\tt Edad} de la hoja de datos
utilizaríamos la expresión {\tt hoja.de.datos\$Edad}, pero hay una forma
más cómoda. Consiste en ``conectar'' la hoja de datos para que puedas
referirte a sus vectores directamente por su nombre:
\index{R!hojas de datos!conectar}
\begin{verbatim}
> attach (hoja.de.datos)
> summary (Edad)
Min. 1st Qu. Median Mean 3rd Qu. Max.
12.00 15.00 16.00 15.64 17.00 20.00
\end{verbatim}
Ten en cuenta que este atajo es sólo para {\em leer} los datos de la
hoja, no para modificarlos. Si quieres modificar un vector de la hoja
de datos tienes que usar la notación normal:
\begin{verbatim}
> hoja.de.datos$Edad <- Edad + 10
\end{verbatim}
De hecho, esto modifica el vector en la hoja de datos, pero no verás
los cambios en los atajos hasta que desconectes la hoja de datos y la
vuelvas a conectar. Para desconectar una hoja de datos utiliza la
función {\tt detach()}.
\index{R!hojas de datos!desconectar}
Cuando quieras almacenar una hoja de datos en un fichero utiliza la
función {\tt write.table()}. Su uso básico es darle la hoja de datos y
el nombre del fichero, pero admite varias opciones para personalizar
la forma en la que escribirá los datos en el fichero. Para ver
estos detalles consulta la ayuda sobre la función ejecutando {\tt
?write.table}. \index{R!hojas de datos!escribir en fichero}
\subsection{Valores perdidos}
\index{R!valores perdidos}
En ocasiones te encontrarás con hojas de datos en las que alguna
celda no tiene el dato. Esto puede suceder porque no haya sido posible
averiguar el dato, o porque éste no tenga sentido. En estos casos se
utiliza para esa celda el valor {\tt NA}, que significa que el valor
``no está disponible'' (NA es abreviatura de ``Not Available'').
\index{R!NA@{\tt NA}}
En otros casos sucede que tras efectuar una serie de operaciones sobre
un conjunto de datos algunos de los resultados no tengan sentido
matemático, como por ejemplo una división por cero (recuerda que la
precisión de los procesadores es limitada). En caso de hacer una
operación así {\sf R} no se quejará en absoluto, sino que devolverá el
valor {\tt NaN} que significa que eso ``no es un número'' (NaN es
abreviatura de ``Not a Number'').
\index{R!NaN@{\tt NaN}}
\section{Funciones}
\index{R!funciones}
Como todo buen lenguaje de programación, {\sf R} te permite definir
funciones para tu uso propio. Para definir una función asignas al
objeto (que será tu función) el valor devuelto por la función {\tt
function}. Esta función particular recibe los mismos parámetros que
recibirá tu función, y a continuación una {\em agrupación} de
comandos, encerrados entre llaves y separados con {\tt ;} o saltos de
línea. El valor devuelto por tu función será el valor de la última
expresión de la agrupación.
Por ejemplo si quieres una función que calcule la curtosis de una
muestra:
\begin{verbatim}
> curtosis <- function (x) {
+ n <- length (x)
+ c <- ( (n * (n - 1) * sum((x - mean(x))^4) ) /
+ ( (n - 1) * (n - 2) * (n - 3) * (var(x))^4 ) ) -
+ ( (3 * (n - 1)^2) / ( (n - 2) * (n - 3) ) )
+ c
+ }
> hoja.de.datos = read.table ("muestra.dat")
> attach (hoja.de.datos)
> curtosis (Edad)
[1] -2.921993
> curtosis (Lectura)
[1] -3.191575
> curtosis (TV)
[1] -3.192770
\end{verbatim}
Normalmente las funciones no quedan bien escritas a la primera, por lo
que tendrás que corregirlas una y otra vez. O tal vez quieras definir
más funciones, modificar las que ya tengas escritas, etc. Todo esto
puedes hacerlo más cómodamente si escribes las funciones en un fichero
y lo importas con la función {\tt source()} que vimos antes.
\index{R!funciones!leer desde fichero}
Así por ejemplo tienes escrita la función {\tt curtosis} en el fichero
{\tt curtosis.R}. Si quieres modificarla y volver a usarla después de
modificada no hay problema. Edita el fichero {\tt curtosis.R} para
modificar la función y luego vuelve a importarlo con la función {\tt
curtosis}. Recuerda que la función {\tt source()} ejecuta los comandos
que encuentra en el fichero que le digas, por lo que las funciones que
tengas escritas en el fichero serán redefinidas y estarán lista para
usar al instante.
\begin{ejemplo}{curtosis.R}{Fichero de funciones}
Este fichero contiene la definición de una función, y cada vez que lo
leas con la función {\tt source()} será ejecutado. Por lo tanto las
funciones que contiene son redefinidas, lo que te permite modificar
las funciones y hacer efectivos los cambios sin tener que salir del
entorno.
\end{ejemplo}
\subsection{Control de flujo}
\index{R!funciones!control de flujo}
{\sf R} proporciona la sintaxis necesaria para construir funciones que
mantengan en control del flujo del programa. Nos referimos a los
condicionales y los bucles:
\subsubsection*{Ejecución condicional}
\index{R!funciones!if@{\tt if}}
La forma de contruir una sentencia condicional en {\sf R} es
{\tt if (expresion\_logica) sentencia\_1 else sentencia\_2}. Si la
{\tt expresion\_logica} es cierta (su valor es {\tt TRUE}) se
ejecutará la {\tt sentencia\_1}, en otro caso se ejecutará la {\tt
sentencia\_2}. {\tt sentencia\_1} y {\tt sentencia\_2} pueden ser
también agrupaciones de comandos y/o expresiones.
\begin{verbatim}
> x = 1
> y = 2
> if (x > y) x else y
[1] 2
\end{verbatim}
En las expresiones booleanas puedes emplear los operadores {\tt |}
(OR) {\tt \&} (AND) y {\tt !} (NOT) normales, o si prefieres ahorrar
un poco de tiempo los operadores ``cortocicuitados'' {\tt ||} (OR) y
{\tt \&\&}. \index{R!||@{\tt ||}} \index{R!\&\&@{\tt \&\&}} Estos
operadores lógicos tienen la ventaja de que sólo evalúan la segunda
expresión cuando es necesario.
Para las comparaciones numéricas se utilizan los mismos comparadores
binarios que en el lenguaje C: {\tt $<$}, {\tt $>$}, {\tt $<=$}, {\tt
$>=$}, {\tt !=} y {\tt ==}. Ten cuidado de no utilizar el operador
{\tt =} para comparaciones.
\index{R!funciones!ifelse@{\tt ifelse()}}
Existe además una versión {\em vectorizada} de la construción
condicional. Se trata de la función {\tt ifelse ()}, que recibe tres
vectores {\tt condicion, a, b} y devuelve un vector del tamaño del más
largo. En este vector el elemnto i-ésimo es {\tt a[i]} si {\tt
condicion[i]} es cierto (su valor es {\tt TRUE}) o bien {\tt b[i]}) en
caso contrario.
\begin{verbatim}
> condicion = c (TRUE, FALSE)
> a = c (1, 2)
> b = c (3, 4)
> ifelse (condicion, a, b)
[1] 1 4
\end{verbatim}
\subsubsection*{Ejecución repetitiva}
\index{R!funciones!for@{\tt for}}
Para la ejecución repetitiva de comandos dispones de la construcción
{\tt for (variable in valores) comandos}, donde {\tt variable} es una
variable vacía que irá cambiando de valor en cada iteración tomando
consecutivamente los valores del vector {\tt valores}. Para cada uno
de estos valores se ejecutará la secuencia {\tt comandos}.
\begin{verbatim}
> for (i in 1:3) print (c (i^2, i^3, i^4, i^5))
[1] 1 1 1 1
[1] 4 8 16 32
[1] 9 27 81 243
\end{verbatim}
\index{R!funciones!while@{\tt while}}
Para ejecutar una secuencia {\em mientras} se cumpla una condición
(podría no ejecutarse la primera vez) utiliza la construcción {\tt
while (condicion) comandos}. Así mientras el valor de la expresión
{\tt condicion} sea {\tt TRUE} se seguirá ejecutando la secuencia {\tt
comandos}.
\begin{verbatim}
x = rnorm (1)