Condicionales, ciclos y secuencias
Estructura de decisión
Normalmente, los operadores lógicos y relacionales se utilizan con sentencias de programación condicional si y si no. La sentencia if
se puede utilizar sola o con la sentencia else
. La forma de la sentencia if
es:
# Ejemplo 1
if( <condición verdadera> )
entonces haga esto
# Ejemplo 2
if( <condición verdadera> ){
entonces haga esto
}else{#si no
entonces haga esto otro
}
La condición entre paréntesis usualmente usará un operador relacional para determinar si la condición es verdadera. Cuando la instrucción if
se usa sola y la condición entre paréntesis no es verdadera, entonces no sucede nada. Por ejemplo:
x<-6; y<-2
# Si x es menor o igual que y entonces asigne z
if(x<=y) z<-x+y
# La condición no es verdadera, entonces no sucede nada
# z
# Si la relación es contraria, entonces la condición es verdadera
if(x>=y) z <- x+y
z
## [1] 8
## [1] 8
Para que algo suceda si la condición entre paréntesis no es verdadera, use if
junto con else
para especificar una alternativa. Tenga en cuenta que no hay una condición entre paréntesis después de la instrucción else
. En este caso, el código que sigue a continuación se ejecutará siempre que la condición if
no sea verdadera.
## [1] 12
## [1] 12
En la condición se puede utilizar varios operadores lógicos.
## [1] 5
## [1] 4
## [1] 4
## [1] 5
## [1] 4
Si se pretende evaluar varias condiciones para obtener más de dos valores de respuestas, es posible anidar los condicionales.
## [1] 5
## [1] 4
En R
existe una función útil para reemplazar valores dependiendo de un condicional.
## [1] 4 5 6 7 8 9 10 11 12
## [1] 1 1 1 0 1 1 1 1 1
## [1] 1 1 1 7 1 1 1 1 1
## [1] 4 5 6 NA 8 9 10 11 12
## [1] NA 5 NA 7 NA 9 NA 11 NA
## [1] 4 NA 6 NA 8 NA 10 NA 12
Estructuras de repetición
El control por repetición, o bucle, le permite repetir el código de manera eficiente sin tener que escribir el mismo código una y otra vez. En R
dos expresiones comunes de bucle son for
y while
.
Los bucles for
se utilizan para recorrer un proceso un número específico de veces. Se utiliza una variable de contador (generalmente designada por una letra minúscula i
) para contar cuántas veces se ejecuta el bucle.
Dentro de la sentencia del for
se tiene que especificar una secuencia de recorrido, ya sea con el operador :
o ingresando un vector definido.
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
# Secuencia basada en las posiciones del vector
x <- c("a","b","c","d")
for(i in 1:4){
print(x[i])
}
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
## [1] "a"
## [1] "b"
## [1] "c"
## [1] "d"
Los bucles for
pueden ser anidados uno dentro de otro.
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
## [1] 1
## [1] 3
## [1] 5
## [1] 2
## [1] 4
## [1] 6
## [,1] [,2] [,3] [,4]
## [1,] NA NA NA NA
## [2,] NA NA NA NA
## [3,] NA NA NA NA
## [4,] NA NA NA NA
for(i in 1:ncol(x)){
for(j in 1:nrow(x)){
if(i%%2==0){
x[j,i] <- 2*(i+j)
}else{
x[j,i] <- 2*(i+j)-1
}
}
}
x
## [,1] [,2] [,3] [,4]
## [1,] 3 6 7 10
## [2,] 5 8 9 12
## [3,] 7 10 11 14
## [4,] 9 12 13 16
El bucle while
repite una condición mientras que la expresión entre paréntesis es verdadera y toma la forma
Los bucles While
comienzan probando una condición. Si es verdad, entonces ejecutan el cuerpo del bucle. Una vez que se ejecuta el cuerpo del bucle, la condición se prueba de nuevo, y así sucesivamente, hasta que la condición es falsa, después de lo cual el bucle termina.
## [1] 0
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
Los bucles while
pueden dar lugar a bucles infinitos si no se escriben correctamente. ¡Usa esto con cuidado! A veces habrá más de una condición en la prueba.
z <- 5
set.seed(1) # Establecer semilla de números aleatorios
while(z >= 3 && z <= 10){
moneda <- rbinom(1, 1, 0.5) # número aleatorio bernoulli p=1/2
if(moneda == 1){ # caminata aleatoria
z <- z + 1
}else{
z <- z - 1
}
}
print(z)
## [1] 2
# Para saber cuántas veces hace la caminata se usa un auxiliar
z <- 5
cuenta <- 1
set.seed(1)
while(z >= 3 && z <= 10){
moneda <- rbinom(1, 1, 0.5)
if(moneda == 1){
z <- z + 1
}else{
z <- z - 1
}
cuenta <- cuenta+1
}
print(z)
## [1] 2
## [1] 32
El ciclo repeat
inicia un bucle infinito desde el principio. Estos no se utilizan comúnmente en aplicaciones estadísticas o de análisis de datos, pero tienen sus usos. La única forma de salir de un ciclo de repetición es llamar a break
.
Un posible paradigma podría ser un algoritmo iterativo en el que esté buscando una solución y no quiera detenerse hasta que esté lo suficientemente cerca de la solución. En este tipo de situación, a menudo no se sabe de antemano cuántas iteraciones se necesitarán para “acercarse lo suficiente” a la solución.
# Número de raíces cuadradas
x0 <- 1000
tol <- 1e-08
pasos <- 1
repeat{
x1 <- sqrt(x0)
if(abs(x1-x0) < tol){
break
}else{
x0 <- x1
}
pasos <- pasos+1
}
x0
## [1] 1
## [1] 30
Los argumentos next
y break
son utilizados comúnmente cuando se quiere omitir pasos de un ciclo, o cuando se quiere parar el ciclo en un momento dado, respectivamente.
## [1] 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
## [26] 46 47 48 49 50
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Secuencias
seq()
genera una secuencia regular de númerosrep()
repite un objeto un numero definido de vecesseq_along()
genera una secuencia regular basado en el tamaño del objetoseq_len()
genera una secuencia regular con un tamaño específicosequence()
genera una secuencia concatenando los elementosgl()
genera una secuencia de factores:
genera una secuencia regular de númerosexpand.grid()
crea un marco con todas las posibles combinaciones de vectores o factores
## [1] 1 3 5 7 9
## [1] 5.000000 5.333333 5.666667 6.000000 6.333333 6.666667 7.000000 7.333333
## [9] 7.666667 8.000000
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
## [1] 4 4 4 4 4
## [1] 1 2 3 4 1 2 3 4 1 2 3 4
## [1] "Hola" "Clase" "Hola" "Clase" "Hola" "Clase" "Hola" "Clase" "Hola"
## [10] "Clase"
## [1] 1 2 3 4
## [1] 1 2 1 2 3 4 5
## [1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6 1 2 3 4
## [26] 5 6 7 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9 1 2 3 4 5
## [51] 6 7 8 9 10
## [1] 1 1 1 1 1 1
## Levels: 1
## [1] Juliana Juliana Carlos Carlos Lina Lina Manuela Manuela Adriana
## [10] Adriana
## Levels: Juliana Carlos Lina Manuela Adriana
## [1] Juliana Juliana Juliana Juliana Carlos Carlos Carlos Carlos Lina
## [10] Lina Lina Lina Manuela Manuela Manuela Manuela Adriana Adriana
## [19] Adriana Adriana
## Levels: Juliana < Carlos < Lina < Manuela < Adriana
## [1] 1 1 2 2 3 3 1 1 2 2 3 3 1 1 2 2 3 3
## Levels: 1 2 3
## [1] Chicles Chicles Chicles Chicles Cigarrillos Cigarrillos
## [7] Cigarrillos Cigarrillos Tinto Tinto Tinto Tinto
## [13] Chicles Chicles Chicles Chicles Cigarrillos Cigarrillos
## [19] Cigarrillos Cigarrillos Tinto Tinto Tinto Tinto
## Levels: Chicles Cigarrillos Tinto
## [1] Chicles Cigarrillos Tinto Chicles Cigarrillos Tinto
## [7] Chicles Cigarrillos Tinto Chicles Cigarrillos Tinto
## [13] Chicles Cigarrillos Tinto Chicles Cigarrillos Tinto
## [19] Chicles Cigarrillos Tinto Chicles Cigarrillos Tinto
## Levels: Chicles Cigarrillos Tinto
expand.grid(edad=seq(18,30,by=3), nota=(seq_len(5)/2)+2,
color=gl(3,1,labels = c("Rojo","Verde","Blanco")),
profesion=c("Ingeniero","Arquitecto"))
Números aleatorios
R
posee una colección de funciones para generar números aleatorios dependiendo una probabilidad específica, o bien que pertenezcan a una distribución de probabilidad.
sample()
genera números aleatoriosrnorm(n, mean, sd)
números aleatorios de la distribución Normalrexp(n, rate)
números aleatorios de la distribución Exponencialrgamma(n, shape, scale)
números aleatorios de la distribución Gammarpois(n, lambda)
números aleatorios de la distribución Poissonrweibull(n, shape, scale)
números aleatorios de la distribución Weibullrcauchy(n, location, scale)
números aleatorios de la distribución Cauchyrbeta(n, shape1, shape2)
números aleatorios de la distribución Betart(n, df)
números aleatorios de la distribución t-Studentrf(n, df1, df2)
números aleatorios de la distribución Fisher-Snedecor (F)rchisq(n, df)
números aleatorios de la distribución Pearson (\(\chi^2_v\))rbinom(n, size, prob)
números aleatorios de la distribución Binomialrgeom(n, prob)
números aleatorios de la distribución Geométricarhyper(nn, m, n, k)
números aleatorios de la distribución Hipergeométricarlogis(n, location, scale)
números aleatorios de la distribución Logísticarlnorm(n, meanlog, sdlog)
números aleatorios de la distribución Log-Normalrnbinom(n, size, prob)
números aleatorios de la distribución Binomial Negativarunif(n, min, max)
números aleatorios de la distribución Uniforme
La posibilidad de generar datos aleatorios es bastante útil en estadística y R
tiene la capacidad de hacer esto para un gran numero de funciones y distribuciones. Estas funciones son de la forma rfunc(n, p1, p2, ...)
, donde func
indica la distribución, n
es el numero de datos generado, y p1
, p2
, ...
son valores que toman los parámetros de la distribución. La lista anterior muestra los detalles de cada distribución, y los posibles valores por defecto de los parámetros (si no se indica, significa que el parámetro debe ser especificado por el usuario).
Todas estas funciones se pueden usar reemplazando la letra r
con las letras d
, p
o q
para obtener, la densidad de probabilidad (dfunc(x, ...)
), la densidad de probabilidad acumulada (pfunc(x, ...)
), y el valor del cuartil (qfunc(p, ...)
, con 0 < p < 1
) respectivamente.