jueves, 26 de junio de 2014

Estadística exploratoria de la primera fase del mundial Brasil-2014 y SISTEMA DE GRÁFICOS BASE DE R (PARTE 1)

SE VIENEN LOS OCTAVOS DE FINAL DE LA COPA DEL MUNDO, BRASIL-2014; YA SE CONOCEN LOS 16 EQUIPOS CLASIFICADOS, PERO.....

CÓMO FUE SU RENDIMIENTO EN LA PRIMER FASE?
QUIEN HIZO MÁS GOLES? A QUIEN LE HICIERON MÁS GOLES?
QUIEN HIZO MÁS FALTAS? QUIEN MUERDE MÁS?



Entonces, con el fin de responder estas y otras preguntas, R para Chibchombianos vuelve con este nuevo post cargado de sed de goles y contento con la selección Chibchombia...
Aprovechando en esta ocasión los datos que brinda el mundial para, explicar los fundamentos de funcionamiento del SISTEMA DE GRÁFICOS BASE DE R.

En esta parte (parte 1) mostraré de los gráficos obtenidos usando el sistema base de R, utilizando los datos proporcionados por Google acerca de los equipos que clasificaron a octavos de final.
En la parte número 2 (siguiente post) explicaré como realizar los gráficos aquí mostrados con R y los parámetros básicos de gráficas en R.
(NOTA: por tal motivo no se afanen o se alarmen por el uso indiscriminado de colores ya que he utilizado diferentes colores y diferentes tipos de gráficos, olvidándome del "estilo correcto" de presentación de datos, en beneficio de explicar como cambiar parámetros de los gráficos en R)

A continuación como quedan las llaves (pueden hacer sus predicciones, al final de este post presento mi predicción INTUITIVA con base a los gráficos obtenidos y un poquito de amor a la camiseta):
Fuente: Google


1. EFECTIVIDAD DE LOS PAÍSES CLASIFICADOS (ANOTACIONES, GOLAZOS!):



En el gráfico se puede que, las tres selecciones con mayor número de goles anotados en la primera fase del mundial son Holanda, Colombia y Francia, con 10, 9 y 8 goles respectivamente, seguidas por Alemania, Suiza y Brasil, todas con 7 goles. Los equipos que menos anotaciones han convertido son Grecia y Nigeria, con 2 y 3 goles, respectivamente.

En cuanto a goles en contra se puede observar que Suiza y Argelia, son los equipos que más goles han recibido, con 6 y 5 goles respectivamente; seguidos por Estados Unidos, Uruguay y Grecia, con 4 goles. Por otra parte, los equipos que menos goles han recibido son Bélgica, Costa Rica y México (el arquero de México es tremendo), que solo recibieron un gol; mientras que Brasil, Colombia, Francia y Alemania recibieron 2 tantos.
Ahora bien, los goles a favor y en contra muestran la efectividad de sus delanteros y por otro lado las proezas de las defensas y los arqueros (sin tener en cuenta otro tipo de variables y condiciones), pero entonces para medir el equipo en su totalidad se utiliza la diferencia de goles (goles a favor - goles en contra = diferencia de goles), para la primera fase del mundial tenemos que, aunque Holanda haya anotado 1 tanto más que Colombia, también recibió un gol más, lo cual hace que sean los dos equipos con mejor rendimiento con una diferencia de goles de +7, seguidos de Francia con +6 y de Brasil y Alemania con +5. El caso de Grecia es único, se clasifico con una diferencia de goles de -2 "dejando pelo en el alambre", en mi concepto tuvieron un poco de suerte, pero habría que ver si les funciona con esta Costa Rica que viene a "matar y comer del muerto";
Finalmente, Estados Unidos, Nigeria y Uruguay, se clasificaron con una diferencia de goles de 0.



2. ATAQUE DE LOS PAÍSES CLASIFICADOS A TRAVÉS DE LOS PARTIDOS DE LA PRIMERA FASE:





Brasil es un equipo que siempre trata de mantener el mismo ritmo en todo el partido y durante todos los tres partidos de la primera fase se mantuvo con el balón mucho más tiempo que su rival (>50% de posesión del balón en los 3 partidos); del mismo modo Colombia y Costa Rica, aunque no mantuvieron la mayor cantidad de tiempo el balón que sus rivales (~45% de posesión del balón), son equipos que dejan jugar, mantienen un ritmo constante y son INFALIBLES Y LETALES EN EL CONTRAGOLPE y la generación de opciones de gol, en especial Colombia que tiene la mayor efectividad junto con Holanda, en todo el campeonato. Estos tres equipos, son equipos calientes, que en el segundo tiempo a pulmón definen partidos y soportan humedades y calor de ollas de presión. Con respecto a la posesión del balón, los equipos que más tratan de mantener el balón y de atacar (así no hayan sido tan efectivos, como en el caso de Argentina, exceptuando a Messi), son Argentina, Chile (aunque varía mucho de un partido a otro, es decir, en unos partidos atacaba más que otros), Francia (con gran variación también entre los partidos) y Alemania (que es una máquina de atacar); mientras que los equipos que menos tienen el balón son Estados Unidos, Argelia, y Grecia (aunque este tiene variación entre partidos).

Con respecto a remates y remates directos al arco Francia es la campeona en ataque, los delanteros prueban mucho la media distancia, y la mayoría de balones van directo a la portería, se conviertan en gol o no. Francia es un inquietador con remates y puede verse claramente que así se ha comportado en todos los partidos y supera a los demás equipos considerablemente; del mismo modo Suiza, Argentina y Brasil prueban mucho el arco contrario, aunque varían en comportamiento de un rival a otro. Los equipos que menos prueban la media distancia y rematan al arco son Argelia, Estados Unidos, 
Chile, Costa Rica y México, aunque los tres primeros varían mucho de un partido al otro. Los tiros de esquina para Argentina son un reflejo de su baja definición, supera a los demás países con un margen muy amplio, pero también es evidente que intentan e intentan y por alguna razón no convierten tanto como quisieran; por otra parte, Brasil y Francia son los siguientes que más han cobrado tiros de esquina en el mundial.

3. ATAQUE TOTAL DE LOS PAÍSES CLASIFICADOS A OCTAVOS EN LA PRIMERA FASE:


Con respecto a la totalidad de ataques y posesión del balón promedio en los tres partidos que ha jugado cada seleccionado se puede evidenciar lo siguiente:
Francia remata MUCHO MÁS que la mayoría de los equipos, Seguido por Suiza, Argentina, Brasil y Belgica, mientras que Chile es el equipo que menos remata, seguido de Costa Rica, USA y Argelia. Este mismo comportamiento puede observarse en los remates que van directo al arco, y se puede ver que Colombia, Holanda y Alemania tienen una cantidad de remates al arco similar, pero que a la hora de rematar o definir es muy difícil que no conviertan un gol, quizá porque los remates de media distancia no son su fuerte como es el caso de Messi (Argentina) sino el juego colectivo.
En cuanto a tiros de esquina totales se observan los mismos resultados que el numeral anterior y con respecto a la posesión del balón puede observarse que los equipos que más mantienen el balón a sus pies son Argentina, Chile, Alemania, Francia, Bélgica y Brasil, mientras que los demás equipos tienen posesión de balón similares.


4. RENDIMIENTO EN LA PRIMERA FASE DE LOS PAÍSES CLASIFICADOS A OCTAVOS DE FINAL:




Primero que todo se puede observar que ningún equipo de los clasificados perdió más de 1 partido (Argelia, USA, Nigeria, Suiza, Uruguay, Grecia y Chile perdieron de a un partido en la fase de grupos), y que ninguno empato más de 1 partido en la fase de grupos (Argelia, USA, Alemania, Nigeria, Francia, Costa Rica, Grecia, México y Brasil empataron de a 1 partido en la fase de grupos).

Por otra parte se puede observar que el patron mínimo de rendimiento para que un equipo pase a la segunda fase del mundial es 1 empate, 1 derrota y 1 victoria (Argelia, USA, Nigeria y Grecia cumplieron con este patrón al cual también quería acceder Portugal pero no le alcanzo, y son los 4 equipos con el peor rendimiento de los 16 clasificados a la segunda fase cada uno con 4 puntos y con rivales difíciles por delante).
Por otra parte los 4 equipos con mejor rendimiento en la fase de grupos que lograron 9 puntos de 9 son Colombia, Holanda (estos dos con mayor diferencia de goles), Argentina y Bélgica. 





5. TARJETAS Y JUEGO SUCIO:








Se puede observar que el equipo con menos faltas cometidas y menos tarjetas (1 tarjeta amarilla y 24 faltas) recibidas en lo que va del Mundial es Argentina, y su buen comportamiento se ha mantenido constante en los tres partidos jugados. Al seleccionado Argentino le siguen en muestra de Fair Play y buen comportamiento las selecciones de Alemania, Suiza y Francia; que también se mantienen constantes aunque Francia varia un poco. 

Las selecciones que más han variado en comportamiento con el trascurrir de los partidos son Holanda, Brasil y Bélgica (Colombia también varia un poco pero en menor medida).
Por otra parte las selecciones que más han cometido faltas en lo que va del mundial son Costa Rica, Uruguay, Holanda, Argelia, Colombia, Grecia y Bélgica en ese orden.
La gravedad de las faltas puede ser medida también por el número de tarjetas amarillas y rojas obtenidas en los primeros tres partidos, en este sentido, los equipos que se ganaron más tarjetas amarillas son Uruguay (6), Grecia (6), México (5), Argelia (5), Bélgica (4), Francia (4), Chile (4), Brasil (4).
Mientras que Holanda, a pesar de cometer tantas faltas, solo tiene 3 tarjetas amarillas y Colombia y Costa Rica 2 cada una. 
Con respecto a las tarjetas rojas, solo 2 de los equipos clasificados obtuvieron cada uno una tarjeta roja, Uruguay y Bélgica. 

TENIENDO EN CUENTA QUE URUGUAY TIENE EL MAYOR NÚMERO DE TARJETAS AMARILLAS, TIENE UNA TARJETA ROJA, Y ES EL SEGUNDO EQUIPO QUE HA COMETIDO MÁS FALTAS, ESTA CLARO QUE DE LOS EQUIPOS CLASIFICADOS URUGUAY ES EL EQUIPO MÁS SUCIO O "PUERCO" PARA JUGAR. (sin mencionar a Luis "mordelon" Suarez quien fue suspendido por un comportamiento que no tiene presentación).


Nota: independientemente de que a Uruguay le toque jugar en octavos contra Colombia, en mi opinión la sanción a Suarez es justa, lo que hizo no tiene forma de ser aceptado.
Y advierto que gane o pierda Colombia, nuestra selección es UN EQUIPO!
Y no por el hecho de que Radamel Falcao García no este jugando, estamos anticipando, pronosticando o justificando nuestras derrotas, así Falcao sea una pieza clave en nuestra cuadrilla! Así que Uruguay tiene que responder sin Suarez como Francia responde sin Ribery o Colombia sin Falcao (AUN MÁS PORQUE EL SE HIZO SACAR DEL MUNDIAL Y NO FUE POR LESIÓN). Y ganemos o perdamos no se justificara por la presencia de Falcao o la ausencia de Suarez.


6. QUIEN ES EL MÁS "MORDELON"?:


"Obviamente sho soy el ma' mordelon" Luis Suarez 


######################################################################
######################################################################
######################################################################

LES DEJO MI APUESTA/PREDICCIÓN DE COMO RESULTARÁ EL MUNDIAL...
espero que hayan disfrutado este post y para la próxima (parte 2), les compartiré como se hacen los gráficos que les presente, el código, scripts, datos, parámetros y fundamentos del sistema de gráficos base de R. 

HASTA LA VISTA Y "QUE VIVA CHIBCHOMBIA, MI PATRIA QUERIDA, CON AGUARDIENTE 'MAGUILA'"



viernes, 6 de junio de 2014

taxize: SUPER-Paquete de R para obtener Información taxonómica de la red (Tutorial Y Chisme)


Finalmente hace poco, Scott Chamberlain y Eduard Szoecs formalizaron y presentaron su paquete de R "taxize" que, en mi opinión es uno de los paquetes más útiles en la actualidad taxonómica en el mundo. 


En este nuevo post me propongo explicar, como siempre en R para Chibchombianos, de la manera mas desmenuzada posible algunas de las aplicaciones del paquete y algo de chisme que puede ser de utilidad. 

1. INSTALACIÓN DE taxize:
Primero que todo, taxize funciona en versiones de R superiores o iguales a 2.10.0 y requiere o hace uso de los paquetes XMLRCurl (≥ 1.6), stringrplyrhttr (≥ 0.2), RJSONIOforeachapeTaxonstandreshape2data.tableveganassertthat.
Aunque Chamberlain y Szoecs escribieron el articulo de presentación, el paquete fue creado realmente por 
Scott Chamberlain, Eduard Szoecs, Carl Boettiger, Karthik Ram, Ignasi Bartomeus y John Baumgartner y esta disponible para Linux, Mac y Windows.

>install.packages("taxize") ## Instalar el paquete taxize
>library(taxize) ## Cargar el paquete taxize a R



2. RESOLVIENDO NOMBRES TAXONÓMICOS:
Usualmente tenemos listas de nombres de especies y en algunas ocasiones queremos saber si estos nombres están escritos correctamente y son los nombres aceptados y actualizados o quizá tal vez queramos saber el nombre científico de un espécimen del cual solo tenemos el nombre común; una forma para lograr estos objetivos sería por ejemplo acudir al Global Names Resolver (GNR) que es mantenido por Encyclopedia of Life.
Supongamos que tenemos 3 nombres en nuestra base de datos que están mal escritos:
Diaclorus curvipes, Hommo sapiens y Homotherim zerum; entonces, para revisar si nuestros nombres están bien escritos utilizamos la función gnr_resolve():

>nom_resueltos <- gnr_resolve(names = c("Diaclorus curvipes", "Hommo sapiens", "Homotherium zerum"))
## Mirar como se escriben los 3 nombres correctamente

Hemos creado un objeto en R llamado 'nom_resueltos' que es de tipo 'Lista' y para ver lo que contiene esta lista le damos:

>nom_resueltos

Podemos entonces ver los resultados de nuestra búsqueda en la consola de R:

$results
       submitted_name                           matched_name
1  Diaclorus curvipes  Diachlorus curvipes (Fabricius, 1805)
2  Diaclorus curvipes  Diachlorus curvipes (Fabricius, 1805)
3  Diaclorus curvipes    Diachlorus curvipes Fabricius, 1805
4  Diaclorus curvipes  Diachlorus curvipes (Fabricius, 1805)
5  Diaclorus curvipes Diachlorus curvipes (Fabricius, 1805 )
6  Diaclorus curvipes  Diachlorus curvipes (Fabricius), 1805
7  Diaclorus curvipes    Diachlorus curvipes Fabricius, 1805
8  Diaclorus curvipes  Diachlorus curvipes (Fabricius, 1805)
9  Diaclorus curvipes    Diachlorus curvipes Fabricius, 1805
10 Diaclorus curvipes                 Diachlorus curvipes F.
11 Diaclorus curvipes                    Diachlorus curvipes
12 Diaclorus curvipes    Diachlorus curvipes Fabricius, 1805
13 Diaclorus curvipes Diachlorus curvipes (Fabricius, 1805 )
14 Diaclorus curvipes  Diachlorus curvipes (Fabricius, 1805)
15      Hommo sapiens            Homo sapiens Linnaeus, 1758
16      Hommo sapiens                           Homo sapiens
17      Hommo sapiens            Homo sapiens Linnaeus, 1758
18      Hommo sapiens            Homo sapiens Linnaeus, 1758
19      Hommo sapiens                           Homo sapiens
20      Hommo sapiens            Homo sapiens Linnaeus, 1758
21      Hommo sapiens                           Homo sapiens
22      Hommo sapiens            Homo sapiens Linnaeus, 1758
23      Hommo sapiens                        Homo sapiens L.
24      Hommo sapiens                           Homo sapiens
25      Hommo sapiens                           Homo sapiens
26      Hommo sapiens                           Homo sapiens
27      Hommo sapiens            Homo sapiens Linnaeus, 1758
28      Hommo sapiens                           Homo sapiens
29      Hommo sapiens            Homo sapiens Linnaeus, 1758
30      Hommo sapiens            Homo sapiens Linnaeus, 1758
31      Hommo sapiens            Homo sapiens Linnaeus, 1758
32      Hommo sapiens                           Homo sapiens
33      Hommo sapiens                           Homo sapiens
34      Hommo sapiens            Homo sapiens Linnaeus, 1758
35      Hommo sapiens                           Homo sapiens
36  Homotherium zerum                      Homotherium serum
                                 data_source_title score
1                                Catalogue of Life  0.75
2                                          Union 4  0.75
3                                          Union 4  0.75
4                           GBIF Backbone Taxonomy  0.75
5                                              EOL  0.75
6                                              EOL  0.75
7                                              EOL  0.75
8                                        BioLib.cz  0.75
9                                            nlbif  0.75
10                         Index to Organism Names  0.75
11                                   uBio NameBank  0.75
12                                   uBio NameBank  0.75
13                                   uBio NameBank  0.75
14                                          Arctos  0.75
15                                            ITIS  0.75
16                                            NCBI  0.75
17                                         Union 4  0.75
18 Interim Register of Marine and Nonmarine Genera  0.75
19                                        Freebase  0.75
20                          GBIF Backbone Taxonomy  0.75
21                                             EOL  0.75
22                                             EOL  0.75
23                                             EOL  0.75
24                                       AskNature  0.75
25                                        BioPedia  0.75
26                                           AnAge  0.75
27                The National Checklist of Taiwan  0.75
28                                         CU*STAR  0.75
29             IUCN Red List of Threatened Species  0.75
30                                       BioLib.cz  0.75
31                                           nlbif  0.75
32                         Index to Organism Names  0.75
33                                   uBio NameBank  0.75
34                                   uBio NameBank  0.75
35                                          Arctos  0.75
36                                     Wikispecies  0.75


De este modo vemos que se consultaron 36 veces los nombres que habíamos introducido en el análisis (14 Diaclorus curvipes, 21 Hommo sapiens y 1 vez Homotherium zerum), como se escriben en realidad: Diachlorus curvipes, Homo sapiens y Homotherium serum, también se puede observar las bases de datos consultadas en cada caso, por ejemplo Wikispecies, uBio NameBank, EOL, Arctos, etc etc. y también el score o valor con el cual concuerda el nombre consultado con el nombre real bien escrito.


3. RECUPERANDO NOMBRES DE NIVELES TAXONÓMICOS SUPERIORES:
Cuando tenemos una lista de nombres de algunos taxa, podríamos querer los nombres de los niveles jerárquicos superiores a los que esos taxa pertenecen (familia, orden, etc).
Las principales bases de datos (pero no las únicas) que taxize utiliza para hacer esto son: Integrated Taxonomic Information System (ITIS) y National Center for Biotechnology Information (NCBI).
Entonces, suponiendo que tenemos las especies Tabanus occidentalis y Canis latrans y queremos saber su clasificación, para eso utilizamos la función classification():

>lista_especies <- c("Tabanus occidentalis", "Canis latrans") 
## Se construye la lista de especies
>classification(lista_especies, db = "itis") 
## Busco la clasificación de cada una de mis especies en la lista utilizando la base  
## de datos ITIS

$`Tabanus occidentalis`
                   name         rank
1              Animalia      Kingdom
2             Bilateria   Subkingdom
3           Protostomia Infrakingdom
4             Ecdysozoa  Superphylum
5            Arthropoda       Phylum
6              Hexapoda    Subphylum
7               Insecta        Class
8             Pterygota     Subclass
9              Neoptera   Infraclass
10         Holometabola   Superorder
11              Diptera        Order
12           Brachycera     Suborder
13         Tabanomorpha   Infraorder
14            Tabanidae       Family
15            Tabaninae    Subfamily
16             Tabanini        Tribe
17              Tabanus        Genus
18 Tabanus occidentalis      Species

$`Canis latrans`
            name         rank
1       Animalia      Kingdom
2      Bilateria   Subkingdom
3  Deuterostomia Infrakingdom
4       Chordata       Phylum
5     Vertebrata    Subphylum
6  Gnathostomata  Infraphylum
7      Tetrapoda   Superclass
8       Mammalia        Class
9         Theria     Subclass
10      Eutheria   Infraclass
11     Carnivora        Order
12    Caniformia     Suborder
13       Canidae       Family
14         Canis        Genus
15 Canis latrans      Species

attr(,"class")
[1] "classification"
attr(,"db")
[1] "itis"


>classification(lista_especies, db = "gbif")
## Busco la clasificación de cada una de mis especies en la lista utilizando la base de datos del GBIF (Global Biodiversity Information Facility)



$`Tabanus occidentalis`
                  name    rank
1             Animalia kingdom
2           Arthropoda  phylum
3              Insecta   clazz
4              Diptera   order
5            Tabanidae  family
6              Tabanus   genus
7 Tabanus occidentalis species

$`Canis latrans`
           name    rank
1      Animalia kingdom
2      Chordata  phylum
3      Mammalia   clazz
4     Carnivora   order
5       Canidae  family
6         Canis   genus
7 Canis latrans species

attr(,"class")
[1] "classification"


Como se puede observar, dependiendo de la base de datos utilizada la clasificación es más profunda o menos profunda; con la base de ITIS se logran recuperar más niveles taxonómicos (Subfilo, Subclase, etc) que los que se logran recuperar con la base de datos de GBIF (e incluso algunas bases de datos no tienen información para especies determinadas).
Es posible que uno no este interesado en toda la información taxonómica de la especie, sino por ejemplo solo quiera saber el género, o la tribu o la familia, para eso entonces utilizamos la función tax_name ():

>tax_name(query = "Megaptera novaeangliae", get = "family", db = "itis")
## consultamos la familia de la ballena jorobada (
Megaptera novaeangliae)


           family
1 Balaenopteridae

>tax_name(query = "Coendou bicolor", get = "order", db = "itis")
## Consultamos el orden del puercoespin común (Coendou bicolor)

     order
1 Rodentia

>tax_name(query = "Tabanus chiribiquensis", get = "family", db = "itis")
## Cuando consultamos una especie que no ha sido aun ingresada a 
## ninguna base de datos (por ejemplo, Tabanus chiribiquensis, una especie de 
## Tábano recientemente descrita en Colombia) no obtenemos ningún resultado.

  family
1     NA


4. OBTENER UNA FILOGENIA:
Muchos investigadores necesitan filogenias en algunos de sus análisis, pero en ocasiones estos investigadores no están bien entrenados en reconstrucción filogenética, por lo cual necesitan obtener árboles filogenéticos de una manera alternativa.
Una de las formas para construir filogenias para Angioespermas, en este caso, es un paquete llamado "Phylomatic"; de tal modo que 'taxize' creo una conexión con ese paquete para crear filogenias. (Nota: Hay que tener en cuenta que Phylomatic no construye filogenias para todas las especies que uno pretenda utilizar sino las que estén disponibles en las bases de datos que el utiliza)


>taxa <- c("Poa annua", "Helianthus tuberosus", "Helianthus annuus")
## Hacer una lista de 3 especies para construir el árbol con 'Phylomatic'

>arbol <- phylomatic_tree(taxa = taxa)
## Construir el árbol de los tres taxa de la lista

>plot(arbol)
## Graficar el árbol en R. 



5. OBTENER LOS NOMBRES DE LAS CATEGORÍAS POR DEBAJO DEL NIVEL TAXONÓMICO ACTUAL:
Algunas veces necesitamos saber los nombres de las categorias que estan por debajo de nuestro nivel taxonómico actual, es decir, por ejemplo tenemos el género Canis y nos interesa saber cuales especies están contenidas adentro del género, o tenemos la Familia Phyllostomidae y queremos saber cuales géneros o especies están contenidas dentro de esa familia. Para esto podemos utilizar la función col_downstream():



>col_downstream(name = "Chlorotabanus", downto = "Species")
## Obtengo todas las especies contenidas en el género Chlorotabanus

$Chlorotabanus
  childtaxa_id              childtaxa_name childtaxa_rank
1      8670308 Chlorotabanus crepuscularis        Species
2      8701201    Chlorotabanus fairchildi        Species
3      8633118        Chlorotabanus inanis        Species
4      8633119  Chlorotabanus leucochlorus        Species
5      8633120     Chlorotabanus mexicanus        Species
6      8633121       Chlorotabanus ochreus        Species
7      8633122     Chlorotabanus parviceps        Species
>col_downstream(name="Phyllostomidae", downto="genus")
## Obtengo todos los géneros contenidos en la familia Phyllostomidae

$Phyllostomidae
   childtaxa_id  childtaxa_name childtaxa_rank
1      17583177        Ametrida          Genus
2      17583186          Anoura          Genus
3      17583176          Ardops          Genus
4      17583175         Ariteus          Genus
5      17581359        Artibeus          Genus
6      17581360    Brachyphylla          Genus
7      17583179        Carollia          Genus
8      17583162        Centurio          Genus
9      17583161      Chiroderma          Genus
10     17583185    Choeroniscus          Genus
11     17581224  Choeronycteris          Genus
12     17583196    Chrotopterus          Genus
13     17583152        Desmodus          Genus
14     17583151         Diaemus          Genus
15     17581225        Diphylla          Genus
16     17600928      Ectophylla          Genus
17     17581226       Erophylla          Genus
18     17583184     Glossophaga          Genus
19     17583183    Hylonycteris          Genus
20     17581227   Leptonycteris          Genus
21     17583182   Lichonycteris          Genus
22     17663079     Lionycteris          Genus
23     17583189    Lonchophylla          Genus
24     17583195     Lonchorhina          Genus
25     17583194    Macrophyllum          Genus
26     17581228        Macrotus          Genus
27     17600929      Mesophylla          Genus
28     17583193   Micronycteris          Genus
29     17583192           Mimon          Genus
30     17581229     Monophyllus          Genus
31     17583181    Musonycteris          Genus
32     17583191     Phylloderma          Genus
33     17583187  Phyllonycteris          Genus
34     17600930        Phyllops          Genus
35     17600932    Phyllostomus          Genus
36     17583188       Platalina          Genus
37     17583153    Platyrrhinus          Genus
38     17583159       Pygoderma          Genus
39     17583178     Rhinophylla          Genus
40     17583180  Scleronycteris          Genus
41     17583158 Sphaeronycteris          Genus
42     17581230      Stenoderma          Genus
43     17583157        Sturnira          Genus
44     17583190         Tonatia          Genus
45     17663081        Trachops          Genus
46     17583156        Uroderma          Genus
47     17583155      Vampyressa          Genus
48     17583154      Vampyrodes          Genus
49     17663080        Vampyrum          Genus
>col_downstream(name="Rhinocerotidae", downto="species")
## Obtener las especies que se encuentran dentro de la familia Rhinocerotidae


$Rhinocerotidae
  childtaxa_id           childtaxa_name childtaxa_rank
1     17000921    Ceratotherium cottoni        Species
2     17000837      Ceratotherium simum        Species
3     17000838 Dicerorhinus sumatrensis        Species
4     17000839         Diceros bicornis        Species
5     17000840     Rhinoceros sondaicus        Species
6     17000841     Rhinoceros unicornis        Species



Hay que tener en cuenta que por ejemplo si queremos saber las especies contenidas dentro de un género no tomará tanto tiempo a que si queremos saber las especies contenidas en una familia o un orden.
Por ejemplo, si yo quiero saber las especies contenidas en el género Chlorotabanus, la lista que obtendré de la función es de solo 7 especies, mientras que si quisiera saber TODAS las especies contenidas dentro de la familia Tabanidae la lista que obtendré de la función es de 4406 especies.



6. OBTENER EL ESTATUS IUCN (LISTA ROJA DE ESPECIES AMENAZADAS) DE UNA ESPECIE EN PARTICULAR, O DE VARIAS:
A veces para ciertas labores de investigación se necesita saber el estatus/estado de conservación de una especie, para esto podemos visitar la pagina de IUCN (IUCN Red List of Threatened Species), pero en ciertas ocasiones tenemos que revisar varias especies al mismo tiempo, por lo cual resulta tedioso obtener dicha información; mediantes las funciones iucn_summary() y iucn_status(), es posible hacer esto de manera muy rápida obteniendo información actualizada rápidamente.
De manera que para este ejemplo estamos interesados en 4 especies, el leopardo de las nieves (Panthera uncia), el panda rojo o panda menor (Ailurus fulgens), el rinoceronte de sumatra (Dicerorhinus sumatrensis) y la palma de Myanmar (Corypha taliera).


>estado <- iucn_summary(c("Panthera uncia", "Ailurus fulgens", "Dicerorhinus sumatrensis", "Corypha taliera") 
## Averiguar la información disponible en IUCN para estos cuatro taxa
>ia ## Ver la información obtenida previamente
 
$`Panthera uncia`
$`Panthera uncia`$status
[1] "EN"

$`Panthera uncia`$history
  year   category
1 2002 Endangered
2 1996 Endangered
3 1996 Endangered
4 1994 Endangered
5 1990 Endangered
6 1988 Endangered
7 1986 Endangered

$`Panthera uncia`$distr
 [1] "Afghanistan"        "Bhutan"             "China"              "India"             
 [5] "Kazakhstan"         "Kyrgyzstan"         "Mongolia"           "Nepal"             
 [9] "Pakistan"           "Russian Federation" "Tajikistan"         "Uzbekistan"        

$`Panthera uncia`$trend
[1] "Decreasing"


$`Ailurus fulgens`
$`Ailurus fulgens`$status
[1] "VU"

$`Ailurus fulgens`$history
  year             category
1 1996           Endangered
2 1996           Endangered
3 1994           Vulnerable
4 1990 Insufficiently Known
5 1988 Insufficiently Known

$`Ailurus fulgens`$distr
[1] "Bhutan"  "China"   "India"   "Myanmar" "Nepal"  

$`Ailurus fulgens`$trend
[1] "Decreasing"


$`Dicerorhinus sumatrensis`
$`Dicerorhinus sumatrensis`$status
[1] "CR"

$`Dicerorhinus sumatrensis`$history
  year              category
1 1996 Critically Endangered
2 1994            Endangered
3 1990            Endangered
4 1988            Endangered
5 1986            Endangered

$`Dicerorhinus sumatrensis`$distr
 [1] "Indonesia"                        "Malaysia"                        
 [3] "Myanmar"                          "Bangladesh"                      
 [5] "Bhutan"                           "Brunei Darussalam"               
 [7] "Cambodia"                         "India"                           
 [9] "Lao People's Democratic Republic" "Thailand"                        
[11] "Viet Nam"                        

$`Dicerorhinus sumatrensis`$trend
[1] "Decreasing"


$`Corypha taliera`
$`Corypha taliera`$status
[1] "EW"

$`Corypha taliera`$history
[1] NA

$`Corypha taliera`$distr
[1] "India"

$`Corypha taliera`$trend
[1] NA


attr(,"class")
[1] "iucn"


Podemos ver que aparece disponible la información del estado de conservación de cada una de las cuatro especies, la historia de conservación y categoría IUCN registrada para cada especie, la distribución de cada una de las especies según IUCN, la tendencia en el estado de conservación de las especies (por ejemplo 'decreasing' hace referencia a que el estado de conservación de esta especie esta disminuyendo).
Si solo queremos observar el estado de conservación de cada una de las especies utilizamos el siguiente comando:

>iucn_status(estado)
 Panthera uncia    Ailurus fulgens      Dicerorhinus sumatrensi     Corypha taliera 
  "EN"                "VU"                     "CR"                     "EW" 

Lo cual quiere decir que Panthera uncia se encuentra amenazada (EN: Endangered), Ailurus fulgens se encuentra vulnerable (VU: Vulnerable), Dicerorhinus sumatrensis se encuentra amenazada críticamente o en peligro critico (CR: Critically Endangered), y por último Corypha taliera se encuentra extinta en la naturaleza (EW: Extinct in the Wild) 




Estas son algunas de las cosas que se pueden hacer en taxize, ENTRE MUCHAS OTRAS MÁS! Aquí solo quise compartirles las cosas más llamativas (en mi opinión) que hace el paquete y las que más me gustan, pero ciertamente pueden ir explorando el paquete que de seguro podría ser MUY UTIL. ESPERO LES HAYA GUSTADO ESTE POST, PERO MÁS ALLÁ DE ESO, ESPERO QUE LES SEA DE MUCHA MUCHA MUCHA UTILIDAD. AHÍ LOS DEJO HASTA LA PRÓXIMA (QUE ESPERO QUE SEA PRONTO).




sábado, 3 de mayo de 2014

CARONTE: Una función en R para crear archivos de landmarks en 2D en formato TNT, a partir de archivos en formato TPS

En 2010, Santiago Catalano, Pablo Goloboff y Norberto Giannini, implementarón el uso de landmarks (datos morfogeométricos) en un contexto filogenético. El enfoque esta basado en encontrar para cada uno de los landmarks, la posición ancestral que minimiza la distancia entre los puntos del ancestro/descendiente (entre las terminales y los nodos) a través del árbol. Maximizando el grado en el cual posiciones similares de cada uno de los landmarks en diferentes taxa puedan estar representando o sean explicados por ancestría común(es decir, via Parsimonia). (Catalano et al., 2010).

Los algoritmos para la optimización de landmarks bajo el principio de parsimonia son descritos en (Goloboff & Catalano, 2011) y el método esta basado en una primera aproximación usando rejillas y subsecuente-mente haciendo un refinamiento iterativo de los puntos inicialmente estimados. Estos algoritmos son implementados en el programa TNT (Tree Analysis using New Technologies; Goloboff et al. 2003, 2008).
Recientemente, Catalano & Goloboff (2012) presentaron un método que utiliza los dos pasos (mapeo y alineamiento de configuraciones) dentro de un solo proceso al mismo tiempo, en el que para un árbol dado, se producen múltiples alineamientos y asignaciones de estados ancestrales, tales que la sumatoria de las distancias euclidianas entre los landmarks correspondientes a través de los nodos del árbol son minimizadas.


Finalmente, ellos implementaron búsquedas de árboles  usando datos continuos de información morfogeométrica/landmarks, pero por ahora este artículo no ha sido publicado. (comunicación personal) 


Como ya lo dije, TNT implementa el uso de landmarks en un contexto filogenético. Entonces, este programa toma los datos de landmarks en formato TNT (.tnt) para hacer sus análisis.
El problema es que la mayoría de programas que se usan para digitalizar landmarks en 2D y 3D (TPSdig, Morpheus, Morphologika, etc) e incluso los paquetes de R que entre sus funciones tiene la digitalización de landmarks (shapes, geomorph, etc) dan como output o escriben los datos de coordenadas en formato TPS, el cual casi que podría decirse que es el formato universal de datos de landmarks. 
Santiago Catalano resolvió este problema de incompatibilidad de formatos, y escribió un pequeño programa en MS-DOS, llamado TPS2TNT, el cual permite escribir archivos TNT desde un archivo TPS. 
Este programa, a pesar de ser muy útil y hasta el momento el único de su tipo posee algunas limitaciones prácticas para su utilización (entre otras):

-Al ser escrito para MS-DOS, restringe su utilización a usuarios del sistema operativo de Microsoft Windows. (aunque podría intentarse usar bajo wine en Linux y/u otro tipo de programas en Mac OS )
-Aunque se han publicado en la red tutoriales o algunas instrucciones para su utilización, 
e incluso video-tutoriales, la verdad es que la interfaz y las instrucciones del programa son muy poco amigables con el usuario, y ademas esta poco documentado tanto su código como su utilización.


-El programa, en algunas ocasiones, no recibe archivos en formato TPS que hayan sido generados por otro software sin antes ser limpiados de algunas lineas que hacen imposible su utilización. (Por ejemplo, el programa tpsRelw, adiciona a los archivos .tps comentarios como el siguiente para cada especie que esta en el archivo:


COMMENT=GLS aligned (from tpsRelw, ver. 1.49)

de manera que para poder utilizar TPS2TNT, el usuario debe previamente eliminar estas lineas una por una manualmente dentro de su archivo en formato .tps, lo cual hace un poco tediosa la manipulación y aumenta por supuesto el tiempo requerido a medida que aumenta el número de taxa del análisis.


CARONTE:

Caronte, es una función que permite pasar archivos de datos de landmarks de 2 dimensiones en formato TPS (.tps) a formato TNT (tnt), que trata de evitar los problemas prácticos que sufre TPS2TNT. 
Caronte fue escrita en lenguaje R, por Ambrosio Torres (quien les escribe) del Laboratorio de Sistemática & Biogeografía, Universidad Industrial de Santander (Bucaramanga, Colombia), esta función necesita que este instalado el paquete 'geomorph' de R, escrito por Dean Adams, Erik Otarola-Castillo, Emma Sherra y que la versión de R instalada en el computador sea ≥ 2.10.
Caronte fue escrita utilizando R 3.1.0. en una distribución Ubuntu 12.04 de 64 bits (x86_64-pc-linux-gnu), bajo licencia GPL (>= 2).

El nombre de la función esta basado en la mitología griega, específicamente en Caronte, quien era el barquero de Hades, el encargado de guiar las sombras errantes de los difuntos recientes de un lado a otro del rio Aqueronte si tenían un Óbolo para pagar el viaje, razón por la cual en la Antigua Grecia los cadáveres se enterraban con una moneda bajo la lengua. Aquellos que no podían pagar tenían que vagar cien años por las riberas del Aqueronte, tiempo después del cual Caronte accedía a portearlos sin cobrar.

Como se usa la función:


Una vez hayas descargado la función del repositorio de GibHub, (recuerda que la función se llama 'caronte.R' ), solo tienes que cargar el archivo en R o RStudio con el siguiente comando:

>source('~/Desktop/my_folder/caronte.R')

El cuerpo de la función es el siguiente: 
>caronte(x, algn = TRUE, w_algn_tps = FALSE)



La función puede tomar tres argumentos que el usuario puede manipular libremente:

-x es el nombre del archivo tps sin el .tps (por ejemplo, si tu archivo tps es llamado "datos.tps" tu solo pondras "datos"

-algn es un argumento para alinear tus configuraciones/datos. Si tu escoges TRUE o T, caronte llamara a la función 'gpagen' del paquete "geomorph", esta función hará un análisis generalizado de Procrustes (que puede ser para 2 o 3 dimensiones, 2 en nuestro caso). Mientras si tu escoges FALSE o F, significa que tu no quieres alinear tus datos o que quizá tus datos fuerón previamente alineados usando otro programa o el mismo R. Por defecto el argumento algn es TRUE.


-w_algn_tps es un argumento que permite escribir los datos que acaban de ser alineados (obviamente en el caso de que tu hubieras escogido alinear tus datos, algn = T), de manera que si tu escoges w_algn_tps = TRUE o R, caronte llamara la función 'writeland.tps' del paquete "geomorph", esta función escribe los nuevos datos que han sido alineados, en un archivo llamado "aligned_data.tps" dentro de tu directorio de trabajo, usando los datos originales sin alinear. En caso de que tu escojas FALSE o F, significa que tu no quieres escribir tus datos alineados en un archivo diferente del original. Por defecto, w_algn_tps is FALSE.

FINALMENTE LA FUNCIÓN ESCRIBIRA EN NUESTRO DIRECTORIO DE TRABAJO, UN ARCHIVO EN FORMATO TNT QUE CONTENGA NUESTROS DATOS, LLAMADO "data_to_tnt.tnt".


Aquí tienen algunos ejemplos acerca de como usar la función caronte en la consola de R o en RStudio:
>caronte("datos") ## si no especificas algn y w_algn_tps, los valores serán tomados por ##defecto
>caronte("datos", algn=FALSE, w_algn_tps =TRUE)
>caronte("datos", algn=T)
>caronte("datos", w_algn=T)
En el repositorio de GitHub hay 3 archivos de ejemplo para que puedan usar y probar la función en R, el primero es un archivo llamado "aves_birds.tps", que son los datos originales, después hay una archivo llamado "aves_birds.tnt" que muestra como quedan los resultados en formato tnt después de haber utilizado la función caronte.
El úlitmo archivo es llamado "aves_birds_algn.tps" que muestra como quedan escritos los datos alineados en formato tps después de haber utilizado la función caronte.


Espero pronto poderles escribir nuevamente ya que tenía re-abandonado el blog, pero es que ahora tengo muchísimas cosas por hacer y ando ocupado hasta el cansancio.

Espero también que les haya gustado la función y tan pronto como pueda les enseñare la extensión de la función caronte para datos en 3 dimensiones. Y así mismo como ya lo prometí utilizaré como guia el código de caronte para explicar principios básicos de programación en R.
HASTA PRONTO!! 

martes, 2 de julio de 2013

Funciones en R (principios y fundamentos)

Finalmente, y después de varios intentos (entre ocupaciones y pereza) logré
escribir otra vez un nuevo post para mi "R para Chibchombianos".
Entre otras cosas, ahora que lo pienso es hasta liberador escribir aquí porque
no me tengo que preocupar por las formas, las criticas o los estilos y si puedo
seguir mis propios caminos y entregar lo que quiero dar y como quiero hacerlo,
que es el fin ultimo del blog :D (gracias por leer, a quien lo haga!)

Como lo había prometido, tenla desde hace rato pensado escribir (empezar a escribir)
sobre funciones y programación en R...Para el inicio decidí entonces realizar este post
acerca de las cosas necesarias/obligatorias que se deben saber antes de entrar de lleno
a funciones, paquetes, lenguaje y demás, para esto he escogido algunos temas de interés,
espero les guste, aprendan y lo disfruten.

**Modo de Batch

R tiene dos modos de trabajo básicos (Interactivo y Batch) sin contar programas de manejo
como Rstudio; el modo interactivo es el que conocemos
cuando iniciamos una sesión de R en windows, este modo es el más "amigable" para los usuarios
nuevos, pero para objetivos de programación es altamente disfuncional y lento.

El modo Batch por el contrario, se encarga de automatizar sesiones en R, correr scripts
y ser flexible a nuestras necesidades, sin necesidad de abrir R y seguir POR PASOS y manualmente
una serie de comandos para obtener un producto final.
Lo que se debe hacer entonces, es poner el código de nuestro análisis o función dentro de
un archivo que la mayoría de veces termina en .R (recomendable), aunque puede ser un .txt,
entre otros.

Por ejemplo, creamos un archivo de texto llamado "yayirobe.R" que contenga lo siguiente:

------------------------------------------------------------------------------------
pdf("prueba_hist.pdf") # Doy un nombre al archivo que contendrá el "output" en .pdf
hist(rnorm(200)) # Genero 200 números y hago un histograma con ellos
dev.off() # Cierro el archivo que contiene el histograma
------------------------------------------------------------------------------------
Todo lo que esta después de # (numeral) en cada linea de comandos del archivo son comentarios
y estos serán ignorados por el interprete de R, estos comentarios sirven para recordarnos
que es lo que estamos haciendo con cada linea de comandos. (solo se ejecutara en R lo que esta
antes del # en cada linea.
Con el modo Batch, es posible ejecutar cientos o miles de ordenes y lineas en R de modo automático
y rápido, en este caso solo ejecutamos tres lineas de comandos para generar un histograma.
Específicamente:

1. pdf("prueba_hist.pdf") --->llamamos la función pdf para decirle a R que queremos guardar
el gráfico en un archivo llamado "prueba_hist.pdf"

2. hist(rnorm(200)) --->genero 200 números al azar que tienen distribución normal, con
rnorm(random normal) que van de 0 a 1, y hago un histograma con estos números utilizando la función hist

3. dev.off()  --->cierro la ventana o "device" en el que se escribirá el histograma al archivo
que nombramos anteriormente (prueba_hist.pdf), y el archivo se escribe en el directorio en el cual
estemos trabajando.

Finalmente se puede ejecutar este archivo (yayirobe.R) para obtener el pdf con el histograma,
de dos formas. En windows, abriendo R y dándole click en las pestañas superiores y escogiendo el archivo.

En linux, como me parece mejor, no hay necesidad de abrir R y se puede ejecutar el archivo
directamente desde la consola (konsole) del sistema con el comando:

$ R CMD BATCH yayirobe.R




**Introducciòn a funciones en R

Una función es un grupo de instrucciones que toma un "input" o datos de entrada, usa estos datos
para computar otros valores y retorna un resultado/producto.
Para empezar con un pequeño ejemplo, definiremos dos funciones con las cuales se puedan calcular
el porcentaje de  purinas y pirimidinas en una secuencia de ADN.
Llamaremos al archivo que contiene las funciones "puripiri.R" :
------------------------------------------------------------------------------------
# calcular el porcentaje de purinas y pirimidinas en una secuencia de ADN
Purinas<-function(x) {
    Purinas <- 0 # asignar 0 a Purinas
    for (n in x) {
        if (n == "A") Purinas <- Purinas + 1 # contar las purinas
        if (n == "G") Purinas <- Purinas + 1 # contar las purinas
    }
    return((Purinas/(length(x)))*100)
}

Pirimidinas<-function(x) {
    Pirimidinas <- 0 # asignar el valor de 100 a Pirimidinas
    {
        Pirimidinas <- 100-Purinas(x)
    }
    return(Pirimidinas)
}                       
#> Pirimidinas(c("A","T","T","G","G","G"))
#[1] 33.33333
#> Purinas(c("A","T","T","G","G","G"))
#[1] 66.66667
#> Purinas(c("A"))
#[1] 100
#> Pirimidinas(c("A"))
#[1] 0
------------------------------------------------------------------------------------
Todas las lineas que se encuentran después de un # son comentarios que se agregan al
código de la función. En este caso el primer comentario menciona lo que hacen las funciones
que se van a escribir.
Primero se define la primer función y se le da el nombre que se desee y que se aplicara al objeto x (x), para nuestro caso
el nombre es "purinas" y continuación se empieza a escribir el cuerpo de la función y se escribe después de haber abierto un corchete ({) :

Purinas<-function(x) { 

Le asignamos un valor de 0 (para empezar) al porcentaje de purinas en la secuencia, y a partir
dse este valor empezaremos a hacer el conteo de las purinas para cada base en la secuencia:

Purinas <- 0 # asignar 0 a Purinas

Ahora le decimos que para cada elemento n del objeto x , en este caso la secuencia de ADN, se le aplicara
el resto de el código de la función, en pocas palabras, abrimos un loop:

for (n in x) {

A continuación le decimos lo que debe hacer con cada elemento n del objeto x, cada vez que lo evalué.
Para nuestro caso seria: si (if) el objeto(n) que encuentra en la secuencia(x) es "A" o "G", entonces le sume
1 a Purinas, que antes habíamos asignado un valor de 0; Que pase al siguiente elemento(n) de la secuencia(x)
y que vuelva a hacer lo mismo:

if (n == "A") Purinas <- Purinas + 1 # contar las purinas
if (n == "G") Purinas <- Purinas + 1 # contar las purinas

Finalmente le decimos que cierre la parte de operaciones de la función con el corchete (}) y que lo ue la función nos
debe arrojar (return) es el valor del ((número de las bases que sean Purinas, sobre la longitud (length) de la secuencia(x), es decir, el
length(x) es el mismo número de elementos(n) de x), multiplicado x 100).
En pocas palabras, le decimos que nos arroje como resultado de la función el porcentaje de bases purinicas que se encuentran en la secuencia de
ADN:

 }
    return((Purinas/(length(x)))*100)
}

De este modo, cerramos el cuerpo y terminamos de escribir, nuestra primer función.
Y empezamos a escribir la segunda función, a la que llamaremos "Pirimidinas":

Pirimidinas<-function(x) {

Al igual que como lo hicimos con la primer funciòn, asignamos una variable llamada Pirimidinas
con el valor inicial de 0:

Pirimidinas <- 0 # asignar el valor de 100 a Pirimidinas

Lo siguiente es algo muy importante en R, y es el hecho de que se puede llamar una función dentro de otra función,
en nuestro caso llamaremos la función "Purinas" (previamente creada) y a 100 le restaremos el valor de el resultado de
la función "Purinas" de una secuencia de ADN (x), puesto que el resto de las bases de las secuencias que no son
Purinas, deben explicitamente ser Pirimidinas y como es un porcentaje, el porcentaje de Pirimidinas será 100  menos el
porcentaje de Purinas que ya calculamos previamente:

    {
        Pirimidinas <- 100-Purinas(x)
    }

Finalmente lo que hacemos es decirle a R que nos arroje el resultado de la resta anterior, que es el resultado del porcentaje
de Pirimidinas en la secuencia de ADN:

    return(Pirimidinas)


Para finalizar lo que se ponen, son ejemplos de casos en los que se prueba o se utiliza la función, de tal forma que nos aseguremos
de que las dos funciones esta escritas y definidas correctamente, estos ejemplos, se escriben en forma de comentarios precedidos por
el símbolo de numeral #:

#> Pirimidinas(c("A","T","T","G","G","G"))
#[1] 33.33333
#> Purinas(c("A","T","T","G","G","G"))
#[1] 66.66667
#> Purinas(c("A"))
#[1] 100
#> Pirimidinas(c("A"))
#[1] 0



**Variable Scope

Una variable/objeto que se crea dentro de una función, es llamada una variable local, puesto que es temporal y solo se utiliza
dentro de la función, mientras se efectúan los cálculos u operaciones, y una vez obtenido el resultado esta variable es eliminada.
En nuestra función de ejemplo las variables "Purinas" y "Pirimidinas" a las que les asignamos 0 inicialmente, al igual que la variable
n, son variables locales.

De tal modo que cuando llamemos a "n" por fuera de la función, en la consola de R, nos dira
que el objeto 'n' no existe y que no lo encuentra.
y si llamo a "Pirimidinas" en la consola de R, el me dirá que Pirimidinas es una función que llame con ese nombre
, pero no me lo reconoce como una variable por fuera de la función:
------------------------------------------------------------------------------------
> Pirimidinas(c("A","T","T","G","G","G"))
[1] 33.33333
> n
Error: object 'n' not found
> Pirimidinas
function(x) {
    Pirimidinas <- 0 # asignar el valor de 100 a Pirimidinas
{
    Pirimidinas <- 100-Purinas(x)
}
    return(Pirimidinas)
}
> care_perro <- 08071988
------------------------------------------------------------------------------------
De manera que se pueden definir variables locales dentro de funciones, que tengan los mismos nombres de variables
globales por fuera de la función o inclusive con el mismo nombre de la función, y R no se confundirá y mantendrá ambas variables
como separadas.
Y finalmente la variable "care_perro" es una variable global que creamos por fuera de una función y que contiene el número
08071988 .




**Argumentos por defecto

Consideremos la función:

> firulallo <- function(x,y=5,z=F) { ... }

Esta función la llamamos "firulallo" y "no tiene cuerpo", puesto que dejamos abierto o vacía la definición de la función per se con los corchetes
y los tres puntos, ( { ... } ).
Mientras tanto, lo que si definimos son argumentos que se ejecutaran por defecto, siempre y cuando el usuario no cambie el argumento o lo re-defina,
es decir, para y definimos un valor de 5 y para z, que es una variable lógica la definimos como FALSE o F;
de tal forma que si ejecutamos la función sin cambiar los argumentos por defecto, R utilizará los que definimos al escribir la función.

Para un objeto x, con valor a 100, utilizando los argumentos por defecto:

>firulallo(100)

Para un objeto x, con valor de 100, cambiando los argumentos por defecto:

>firulallo(100, y=60, Z=TRUE)

Para un objeto x, con valor de 126, cambiando solo un argumento por defecto (el otro argumento, el que no cambiemos, se ejecutara por defecto):

>firulallo(126, y=45)


ESO ES TODO POR AHORA Y ESPERO PRONTO PODER COMPARTIR MÁS COSAS Y QUE LES HAYA GUSTADO Y LES PAREZCA MUCHO MÁS FÁCIL AHORA!