y=4
if(y > 3){
y<-10
}else {
y<-0
}
y
## [1] 10
y=4
y<- if(y>3){
10
} else {
0
}
y
## [1] 10
El siguiente constructor es el bucle “for”, probablemente el tipo de bucle más común que usarás en R. La idea básica es que tienes un índice para el bucle, normalmente llamado “i” pero si tienes varios bucles podrías llamarlo “j”, “k”, “l”, etc. Y el índice del bucle recorrerá una secuencia de números, usualmente de enteros. Por ejemplo, aquí tengo un bucle “for” que está iterando entre los números 1 y 10 para lo cual he creado una secuencia usando el operador “1:10”. Este bucle no hace nada particularmente interesante, simplemente imprime los números, es decir, imprime el valor de “i” en cada iteración.
for(i in 1:10){
print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
Existen varias maneras de utilizar un bucle “for”. R es bastante flexible en la forma en la que puedes indexar distintos tipos de objetos. Aquí he creado un vector de caracteres con las letras “a”, “b”, “c” y “d”. Y todos estos bucles son equivalentes. Por ejemplo, en el primero he hecho lo que típicamente ves en otros lenguajes como C que también tienen bucles “for”: tengo un índice “i” que sigue a la secuencia de 1 a 4, una secuencia de enteros, e imprimo el i-ésimo elemento de “x” en cada iteración. Por lo que este bucle imprime “a”, “b”, “c”, “d”. Play video starting at 1 minute 23 seconds and follow transcript1:23 Otra cosa que puedo hacer es utilizar la función “seq_along”, la cual toma como parámetro de entrada un vector y crea una secuencia de enteros que es igual a la longitud de dicho vector. Como en este caso el vector es de longitud 4, entonces creará la secuencia de enteros de 1 a 4. Es exactamente igual a la secuencia anterior en la que usaba directamente “1:4”. Sin embargo, aquí generé la secuencia basado en la longitud de la variable “x”. Ahora mi índice “i” recorrerá esta secuencia imprimiendo el i-ésimo elemento de x, exactamente el comportamiento anterior. Imprimirá “a”, “b”, “c”, “d”. Play video starting at 2 minutes 1 second and follow transcript2:01 En el tercer ejemplo uso una variable diferente como índice, la cual llamo “letter”. Y en este caso, el índice tomará los valores directamente del vector. No hay ningún motivo por el que el índice tenga que ser necesariamente un entero. Puede tomar su valor de elementos de cualquier vector. Ahora, el bucle itera sobre este vector de letras “a”, “b”, “c”, “d” e imprime directamente la letra, es decir, imprime el valor del índice el cual es igual a las letras del vector.
x<- c("a","b","c","d")
for(i in 1:4){
print(x[i])
}
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
for(i in seq_along(x)){
print(x[i])
}
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
for(letter in x){
print(letter)
}
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
for(i in 1:4) print(x[i])
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
Los bucles “for” pueden estar anidados y tener un bucle “for” dentro de otro. Esto es muy común, por ejemplo, con una matriz de dos dimensiones en la que queremos iterar primero sobre las filas y luego sobre las columnas. Aquí, el bucle externo tiene el índice “i” e itera sobre las filas. En él, uso una función llamada “seq_len”. La idea es que “seq_len” toma un entero, que en este caso es el número de filas de “x”, y crea una secuencia de enteros a partir de él. Esta matriz en particular tiene dos filas, así que creará la secuencia de 1 a 2. De la misma manera, el bucle anidado con el índice “j” utiliza el número de columnas para crear la secuencia y como esta matriz tiene tres columnas la función “seq_len” creará la secuencia de enteros de 1 a 3. Por lo tanto, este bucle doble anidado imprimirá todos los elementos de la matriz. Play video starting at 4 minutes 1 second and follow transcript4:01 Una cosa con la que hay que tener cuidado con los bucles anidados es que ir más allá de 2 o 3 niveles, Play video starting at 4 minutes 9 seconds and follow transcript4:09 aunque esté bien teóricamente, hace que el código sea un poco más difícil de leer. Si estás leyendo un código que tiene tres o cuatro bucles “for” anidados, tendrás problemas para entender qué hace. Es cierto que a veces es la aproximación más lógica al problema pero muchas veces hay maneras de evitarlo, como por ejemplo usando funciones.
x<-matrix(1:6, 2, 3)
for(i in seq_len(nrow(x))){
for(j in seq_len(ncol(x))){
print(x[i, j])
}
}
## [1] 1
## [1] 3
## [1] 5
## [1] 2
## [1] 4
## [1] 6
La sentencia “while” es otra de las principales constructoras de bucles en R. La idea principal es que “while” toma una expresión lógica y ejecuta el bucle basándose en el valor de dicha expresión lógica. Por ejemplo, aquí tengo un bucle sencillo: inicializa una variable “count” igual a 0 y mientras “count” sea menor que 10, imprime “count” e incrementa su valor en 1. Tan pronto como el valor de “count” llega a 10, el bucle termina y entonces la ejecución va al próximo bloque de código. El bucle “while” es útil porque hace que el código sea más fácil de leer alguna veces. Resulta obvio en este ejemplo que el bucle debe parar cuando el valor de la variable “count” sea mayor o igual a 10, con lo que lo hace un poco más legible. Sin embargo, debes tener cuidado con los bucles “while” porque técnicamente son bucles infinitos y debes asegurar que se alcanza la condición de parada del bucle. De lo contrario, tu programa nunca terminará. En este caso resulta obvio que el bucle terminará de ejecutarse eventualmente pero en bloques de código más complejos puede ser difícil determinar si el bucle “while” terminará. En casos como esos, suele ser mejor usar bucles “for”, pues estos establecen un límite fijo al número de veces que se ejecutará el bloque. Esto no quiere decir que nunca debes usar bucles “while” pero sí que debes tener cuidado cuando los utilices.
count <- 0
while(count < 10){
print(count)
count <- count +1
}
## [1] 0
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
En un bucle “while”, o en cualquier tipo de constructor como una sentencia “if”, puedes probar varias condiciones lógicas utilizando los operadores lógicos. Por ejemplo, aquí tengo la variable “z” Play video starting at 1 minute 45 seconds and follow transcript1:45 que inicializo con el valor 5 y la condición para el bucle “while” es que “z” sea mayor o igual que 3 y que sea menor o igual que 10. Por lo tanto, mientras “z” esté entre los valores 3 y 10, lo que haré es imprimir el valor de “z”, luego lanzaré una moneda y si el valor de la moneda es 1 entonces incrementaré en 1 el valor de “z”, de lo contrario, si el valor de la moneda es distinto de 1, podría ser 0 o cualquier otro valor, entonces le restaré 1 al valor de “z”. Así que este bucle tiene un componente aleatorio y el valor de “z” aumentará o disminuirá dependiendo del lanzamiento de la moneda.
Por lo tanto, en este ejemplo es difícil decir cuándo terminará el bucle “while”
porque el bloque involucra una generación de números aleatorios. El valor de “z” irá en zigzag hasta que eventualmente llegue a 10 o eventualmente llegue a 3, o a algún valor menor que 3. Esto puede estar bien, pero debes tener cuidado de que no tarde demasiado tiempo.
Una cosa que hay que destacar, a nivel más técnico, es que cuando R evalúa varias condiciones lógicas en una expresión, por ejemplo aquí tengo “z” mayor igual que 3 y “z” menor o igual que 10, las condiciones siempre se evalúan de izquierda a derecha. Primero revisa que la condición que está más a la izquierda sea verdadera y luego va a la siguiente. Así, primero comprobará si “z” es mayor o igual que 3. Si eso es cierto, entonces evaluará la próxima expresión, es decir, comprobará si “z” es menor o igual que 10. Finalmente, si ambas condiciones son ciertas, entonces se ejecutará el bloque del bucle.
La distribución binomial es, sin duda, la más importante de las distribuciones discretas de probabilidad. Una variable X de tipo binomial B(n,p) (n es el número de ensayos y p la probabilidad de éxito en cada uno de esos ensayos) toma valores k de 0 a n
La media, varianza y desviación típica de una distribución binomials se obtienen fácilmente en R con estos comandos (aquí se muestra un ejemplo para una binomial de tipo B(25,0.5)):
. . .La más fácil de entender es la función dbinom. Esta función sirve para calcular la probabilidad de que una variable binomial X de tipo B(n,p) tome un cierto valor k. Por ejemplo, con n=20, k=5 y p=3/7 usaríamos este comando:
dbinom(5,size=20,prob=3/7) que produce como resultado 0.0506978.Introducimos los parametros de la binomial X de tipo B(n,p)
n = 25 p = 0.5 q = 1-p
Calculamos la media, varianza y desviacion tipica
mu = np mu varianza= npq varianza sigma = sqrt(np*(1-p)) sigma
z<-5
while(z >= 3 && z <=10) {
print(z)
coin <- rbinom(1, 1, 0.5)
if(coin == 1){
z <- z+1
} else {
z<- z-1
}
}
## [1] 5
## [1] 4
## [1] 3
## [1] 4
## [1] 3
## [1] 4
## [1] 5
## [1] 4
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 6
## [1] 5
## [1] 4
## [1] 5
## [1] 4
## [1] 3
## [1] 4
## [1] 3
rbinom(1,23000000,prob=0.5) #prob divide en deciles el SIZE (0.1 a 1)
## [1] 11501701
rbinom(20,size=9,prob=4/5)
## [1] 8 7 8 8 9 6 7 8 5 9 8 6 9 8 5 7 7 7 8 6
break y next son palabras reservadas en R, no podemos asignarles nuevos valores y realizan una operación específica cuando aparecen en nuestro código.
break nos permite interrumpir un bucle, mientras que next nos deja avanzar a la siguiente iteración del bucle, “saltándose” la actual. Ambas funcionan para for y while.
for(i in 1:100){
if(i <= 20){
next
}
}
for(i in 1:10) {
if(i == 3) {
break
}
print(i)
}
## [1] 1
## [1] 2
numero <- 20
while(numero > 5) {
if(numero == 15) {
break
}
numero <- numero - 1
}
numero
## [1] 15
for(i in 1:4) {
if(i == 3) {
next
}
print(i)
}
## [1] 1
## [1] 2
## [1] 4
valor <- 0
mi_vector <- NULL
repeat{
valor <- valor + 1
if(valor == 5) {
break
}
}
# Resultado
valor
## [1] 5
suma <- function(x, y){
x+y
}
suma(3, 5)
## [1] 8
above10 <- function(x){
use <- x>10
x[use]
}
above <- function(x, n){
use <- x > n
x[use]
}
above(x, 12)
## integer(0)
Por ejemplo, mira la función “sd”, que calcula la desviación estándar de un juego de números. “sd” toma una entrada “x”, que es el nombre de un argumento que consiste en un vector de datos. Y hay un segundo argumento llamado “na.rm”, que controla si los valores que faltan deben ser eliminados de la entrada o no. El valor por defecto de “na.rm” es “false”. Así que, por defecto, si hay valores faltantes en el juego de datos de entrada sobre los que se desea calcular la desviación estándar, los valores faltantes no serán incluidos. Aquí estoy simulando algunos datos, unos cientos de variables aleatorias con distribución normal.
De manera que si ahora llamo a “sd” sobre el vector, me devolverá una estimación de la desviación estándar. Sería exactamente lo mismo si digo “x” igual a “mydata”, aquí he dado el nombre del argumento, pero los datos son los mismos, así que calcularé la misma desviación estándar. En el primer ejemplo no di nombre al argumento por lo que toma “mydata” por defecto como primer argumento de la función.
sd = desviación estándar
En el siguiente ejemplo voy a dar el nombre de ambos argumentos. Voy a decir “x” igual a “mydata”, y “na.rm” igual a “false”. Eso calcula lo mismo que antes. Cuando nombro los argumentos no necesito ponerlos en ningún orden concreto. Por ejemplo, puedo invertir el orden de los argumentos, como aquí. Digo “na.rm” igual a “false” primero, y luego digo “x” igual a “mydata”, y eso producirá exactamente el mismo resultado porque he nombrado los argumentos. Pero, ¿qué ocurre si doy el nombre de un argumento, pero no del otro?
mydata <- rnorm(100)
sd(mydata)
## [1] 0.9350817
sd(x=mydata)
## [1] 0.9350817
sd(x=mydata, na.rm=FALSE)
## [1] 0.9350817
sd(na.rm=FALSE,x=mydata)
## [1] 0.9350817
sd(na.rm=FALSE, mydata)
## [1] 0.9350817
mydata <- rnorm(10)
sd(mydata)
## [1] 0.6841908
sd
## function (x, na.rm = FALSE)
## sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x),
## na.rm = na.rm))
## <bytecode: 0x00000000145e1850>
## <environment: namespace:stats>
Argument Matching
f<-function(a, b) {
a^2+b
}
f(2,1)
## [1] 5
f2 <- function(a,b,c,d) {
a^3+b^2-c+d
}
f2(64,2,7,2)
## [1] 262143
f2
## function(a,b,c,d) {
## a^3+b^2-c+d
## }
Voy a definir una función muy simple, y a veces este tipo de funciones tienen la forma de algo que podríamos llamar “constructores”. La idea es que la función construya otra función. Esto es lo que quiero hacer: quiero crear una función que se llame “make.power” que defina a otra. “make.power” toma como entrada un número “n”. Y lo que queremos Y dentro de la función “make.power” defino otra función llamada “pow”. Y “pow” va a aceptar un argumento llamado “x”. Lo que va a ocurrir es que la función “pow” va a tomar el argumento “x” y lo va a elevar a la n-ésima potencia, de manera que “make.power” devuelve la función “pow”. En el interior de la función “pow” podemos ver el argumento “x”, que no es un problema, pero “n” es una variable libre porque no está definida en la función “pow”. Sin embargo, “n” está definida en el interior de la función “make.power”, y dado que “pow” se ha definido en ese entorno, encontrará ese valor de “n”. La función “pow” encontrará el valor de “n” en el interior de este entorno. De manera que lo que ocurre si llamo a “make.power” y le paso un número, como por ejemplo el 3, devolverá una función, a la que llamaré “cube”. De manera similar, puedo pasar 2 como argumento para crear una función del tipo “pow” que llamaré “square”. Ahora, si le paso a “cube” el número 3, lo que hace es elevar 3 a la tercera potencia, y obtengo 27. Si llamo a “square” sobre el número 3, elevará 3 a la segunda potencia, y dará 9. Y de esta manera, he conseguido una función capaz de construir muchos tipos diferentes de funciones capaces de elevar a diferentes potencias.
make.power <- function(n){
pow <- function(x){
x^n
}
pow
}
al_cubo <- make.power(3)
al_cuadrado <- make.power(2)
al_cubo(3)
## [1] 27
al_cuadrado(3)
## [1] 9
pow = Calcule Y Trace La Potencia, El Tamaño De Muestra Requerido.
make.power <- function(n){
pow <- function(x){
x^n
}
pow
}
al_cubo <- make.power(3)
al_cuadrado <- make.power(2)
#muestra el exponente de la variable
ls(environment(al_cubo))
## [1] "n" "pow"
get("n", environment(al_cubo))
## [1] 3
#imprime valor de 2 al cubo
al_cubo(2)
## [1] 8
#imprime valor de 2 al cuadrado
al_cuadrado(2)
## [1] 4
#iagual que la función anterior, pero de forma reducida quetando POW este indica que se debe elebar a la enesima potencia, pero en este basto con definir x^n
expo<- function(x,n){
x^n
}
expo(2,3)
## [1] 8
expo(2,2)
## [1] 4
Datos de fecha y hora
x<- Sys.time()
x
## [1] "2020-07-03 19:22:45 -04"
p<-as.POSIXlt(x)
names(unclass(p))
## [1] "sec" "min" "hour" "mday" "mon" "year" "wday" "yday"
## [9] "isdst" "zone" "gmtoff"
p$min
## [1] 22
p$sec
## [1] 45.16216
datestring<-c("January 10, 2012 10:40", "December 9, 2011 9:10")
x <- strptime(datestring, "%B %d, %H:%M")
x
## [1] NA NA
x <- as.Date("2020-07-07")
y <- as.Date("1985-01-02")
x-y
## Time difference of 12970 days
x <- as.POSIXct("2020-07-07 01:00:00")
y <- as.POSIXct("2020-07-07 06:00:00", tz = "GMT")
y-x
## Time difference of 1 hours
x-y
## Time difference of -1 hours