CC BY-NC-ND 3.0
if
if
SI [esto] ENTONCES [esto] SINO [esto]
myVar <- 2
if(myVar < 3){
print("myVar < 3")
}else{
print("myVar > 3")
}
## [1] "myVar < 3"
if
myVar <- TRUE
if(is.character(myVar)){
print("myVar: character")
} else {
if(is.numeric(myVar)){
print("myVar: numeric")
} else {
if(is.logical(myVar)){
print("myVar: logical")
} else {
print("myVar: ...")
}
}
}
## [1] "myVar: logical"
if
if
evalua solo el primer elemento:
prueba <- c(TRUE, FALSE, FALSE)
if(prueba == TRUE){
print("¡SI!")
}
## Warning in if (prueba == TRUE) {: the condition has length > 1 and only the
## first element will be used
## [1] "¡SI!"
if
if
evalua solo el primer elemento:
prueba <- c(TRUE, FALSE, FALSE)
if(prueba[1] == TRUE){
print("¡SI!")
}
## [1] "¡SI!"
if(prueba[2] == TRUE){
print("¡SI (2)!")
}
if
prueba <- c(TRUE, FALSE, FALSE)
if(prueba[1] == TRUE &
prueba[2] == TRUE &
prueba[3] == TRUE){
print("¡SI!")
}
if
prueba <- c(TRUE, FALSE, FALSE)
if(sum(prueba == TRUE) == length(prueba)){
print("¡SI!")
}
if
prueba <- c(TRUE, TRUE, TRUE)
if(sum(prueba == TRUE) == length(prueba)){
print("¡SI!")
}
## [1] "¡SI!"
&
y &&
Con &
R comprobará todas las condiciones, y con &&
R tomará cada condición una después de la otra y continuará solo si es verdadera.
miNumero <- 9
if(is.numeric(miNumero) & miNumero * 10 < 100){
print("Numero menor a 10")
}
## [1] "Numero menor a 10"
&
y &&
miNumero <- "55"
if(is.numeric(miNumero) & miNumero * 10 < 100){
print("Numero menor a 10")
}
Error in miNumero * 10: non-numeric argument to binary operator
&
y &&
miNumero <- "55"
if(is.numeric(miNumero) && miNumero * 10 < 100){
print("Numero menor a 10")
}
switch
switch
miNombre <- "Pablo"
if(miNombre == "Alexa"){
result <- "Hola Alexa"
}
if(miNombre == "Juan"){
result <- "Hola Juan"
}
if(miNombre == "Pablo"){
result <- "Hola Pablo"
}
if(miNombre == "Javier"){
result <- "Hola Javier"
}
print(result)
## [1] "Hola Pablo"
switch
miNombre <- "Pablo"
switch(miNombre,
Alexa = result <- "Hola Alexa",
Juan = result <- "Hola Juan",
Pablo = result <- "Hola Pablo",
Javier = result <- "Hola Javier")
print(result)
## [1] "Hola Pablo"
for
for
bdd <- data.frame(rep01 = rnorm(n = 100, mean = 10, sd = 1),
rep02 = rnorm(n = 100, mean = 10, sd = 1))
print(head(bdd))
## rep01 rep02
## 1 9.848500 10.795274
## 2 10.530403 9.525827
## 3 9.733653 9.393879
## 4 9.252658 9.606791
## 5 10.247308 8.976681
## 6 10.878104 10.051718
for
for (i in 1:5){
print(bdd$rep01[i] - bdd$rep02[i])
}
## [1] -0.9467737
## [1] 1.004576
## [1] 0.3397732
## [1] -0.3541334
## [1] 1.270627
for
letras <- letters
for (i in seq_along(letras)){
if(letras[i] %in% c("a", "e", "i", "o", "u", "y")){
print(paste0("Vocal ", letras[i]," en posición: ", i))
}
}
## [1] "Vocal a en posición: 1"
## [1] "Vocal e en posición: 5"
## [1] "Vocal i en posición: 9"
## [1] "Vocal o en posición: 15"
## [1] "Vocal u en posición: 21"
## [1] "Vocal y en posición: 25"
for
y RR no maneja bien las bucles de tipo for
. Veremos mas tarde como usar alternativas. Mientras tanto, cuando posible, hay que preferir el trabajo con vectores.
La mayorÃa de los ejemplos que se pueden encontrar en Internet sobre el bucle for()
pueden reemplazarse por operaciones vectoriales.
for
y R# [1] FOR
for (i in 1:5){
print(bdd$rep01[i] - bdd$rep02[i])
}
## [1] -0.9467737
## [1] 1.004576
## [1] 0.3397732
## [1] -0.3541334
## [1] 1.270627
# [2] VECTOR
head(bdd$rep01 - bdd$rep02)
## [1] -0.9467737 1.0045758 0.3397732 -0.3541334 1.2706270 0.8263859
for
letras <- letters
# [1] FOR
for (i in seq_along(letras)){
if(letras[i] %in% c("a", "e", "i", "o", "u", "y")){
print(paste0("Vocal ", letras[i]," en posición: ", i))
}
}
## [1] "Vocal a en posición: 1"
## [1] "Vocal e en posición: 5"
## [1] "Vocal i en posición: 9"
## [1] "Vocal o en posición: 15"
## [1] "Vocal u en posición: 21"
## [1] "Vocal y en posición: 25"
# [2] VECTOR
which(letras %in% c("a", "e", "i", "o", "u", "y"))
## [1] 1 5 9 15 21 25
for
y R# numero de números pares
# [1] FOR
x <- sample(1:100, size = 20)
count <- 0
for (val in x) {
if(val %% 2 == 0){
count <- count + 1
}
}
print(count)
## [1] 8
# [2] VECTOR
sum(x %% 2 == 0)
## [1] 8
for
y R# calcular cuadrados
# [1] FOR
x <- rep(0, 20)
for (j in 1:20){
x[j] <- j^2
}
print(x)
## [1] 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289
## [18] 324 361 400
# [2] VECTOR
(1:20)^2
## [1] 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289
## [18] 324 361 400
for
y R# repetir una tirada de dados y promediar
# [1] FOR
ntrials = 1000
trials = rep(0, ntrials)
for (j in 1:ntrials){
trials[j] = sample(1:6, size = 1)
}
mean(trials)
## [1] 3.512
# [2] VECTOR
mean(sample(1:6, ntrials, replace = TRUE))
## [1] 3.538
for
y REs un buen ejercicio explorar los muchos ejemplos disponibles en Internet en el bucle for()
e intentar convertirlos en operaciones vectoriales. Esto nos permite adquirir buenos reflejos de programación con R.
En conclusión, se recomienda no usar el bucle for()
con R siempre que sea posible, y en este capÃtulo veremos alternativas como los bucles familiares apply()
.
while
while
i <- 0
while(i < 4){
print(i)
i <- i + 1
}
## [1] 0
## [1] 1
## [1] 2
## [1] 3
En este ejemplo, la variable i
tiene como valor inicial 0. MIENTRAS QUE i < 4
, mostramos i
con print()
. Para que este bucle finalice, no olvidamos cambiar el valor de i
, esto se hace con la lÃnea i <- i + 1
. Cuando la condición i < 4
ya no se cumple, el bucle se detiene.
while
El bucle while()
es muy útil para crear scripts que realizarán cálculos en variables cuyo valor cambia con el tiempo. Por ejemplo, imaginamos un número entre 0 y 10000 y un generador aleatorio que intentará determinar el valor de este número. Si queremos limitar los intentos de R a 2 segundos, podemos escribir el siguiente script.
while
myNumber <- sample(x = 10000, size = 1)
myGuess <- sample(x = 10000, size = 1)
paste0("Mi numero es: ", myNumber)
## [1] "Mi numero es: 3516"
paste0("El intento de la computadora es: ", myGuess)
## [1] "El intento de la computadora es: 1020"
while
startTime <- Sys.time()
print(startTime)
## [1] "2019-02-15 12:37:12 CET"
while
print(Sys.time() - startTime)
## Time difference of 0.06940413 secs
while
repeticiones <- 0
startTime <- Sys.time()
while(Sys.time() - startTime < 0.5){
repeticiones <- repeticiones + 1
}
print(repeticiones)
## [1] 10565
while
repeticiones <- 0
startTime <- Sys.time()
while(Sys.time() - startTime < 0.5){
repeticiones <- repeticiones + 1
if(repeticiones >= 1000){
break
}
}
print(repeticiones)
## [1] 1000
while
myNumber <- sample(x = 10000, size = 1)
myGuess <- sample(x = 10000, size = 1)
numberGuess <- 0
startTime <- Sys.time()
while(Sys.time() - startTime < 2){
if(myGuess == myNumber){
numberGuess <- numberGuess + 1
print(paste0("Numero encontrado despues de ",
numberGuess, " intentos."))
print(paste0("Y tengo mucho tiempo libre: ",
round(2 - as.numeric(Sys.time() - startTime),
digits = 2), " sec"))
break
}else{
myGuess <- sample(x = 10000, size = 1)
numberGuess <- numberGuess + 1
}
}
## [1] "Numero encontrado despues de 2455 intentos."
## [1] "Y tengo mucho tiempo libre: 1.86 sec"
while
guessNumber <- function(myNumber, myGuess){
numberGuess <- 0
success <- FALSE
startTime <- Sys.time()
while(Sys.time() - startTime < 2){
if(myGuess == myNumber){
numberGuess <- numberGuess + 1
success <- TRUE
break
}else{
myGuess <- sample(x = 10000, size = 1)
numberGuess <- numberGuess + 1
}
}
return(list(numberGuess, success))
}
guessNumber(myNumber = sample(x = 10000, size = 1),
myGuess = sample(x = 10000, size = 1))
## [[1]]
## [1] 19880
##
## [[2]]
## [1] TRUE
while
guessNumber <- function(mySample){
myNumber <- sample(mySample, size = 1)
myGuess <- sample(mySample, size = 1)
numberGuess <- 0
success <- FALSE
startTime <- Sys.time()
while(Sys.time() - startTime < 2){
if(myGuess == myNumber){
numberGuess <- numberGuess + 1
success <- TRUE
break
}else{
myGuess <- sample(mySample, size = 1)
numberGuess <- numberGuess + 1
}
}
return(list(numberGuess, success))
}
guessNumber(mySample = 1:10000)
## [[1]]
## [1] 13907
##
## [[2]]
## [1] TRUE
while
guessNumber2 <- function(mySample){
myNumber <- sample(mySample, size = 1)
myGuess <- sample(mySample, size = 1)
numberGuess <- 0
success <- FALSE
startTime <- Sys.time()
while(Sys.time() - startTime < 2){
if(myGuess == myNumber){
numberGuess <- numberGuess + 1
success <- TRUE
break
}else{
mySample <- mySample[! mySample %in% myGuess]
myGuess <- sample(mySample, size = 1)
numberGuess <- numberGuess + 1
}
}
return(list(numberGuess, success))
}
guessNumber2(mySample = 1:10000)
## [[1]]
## [1] 9040
##
## [[2]]
## [1] TRUE
repeat
repeat
i <- 1
repeat{
print(i)
i <- i + 1
if(i >= 5){
break
}
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
repeat
startTime <- Sys.time()
i <- 1
repeat{
guessNumber(mySample = 1:10000)
i <- i + 1
if(i >= 10){
break
}
}
totalTime <- Sys.time() - startTime
print(totalTime)
## Time difference of 4.049098 secs
repeat
startTime <- Sys.time()
i <- 1
repeat{
guessNumber2(mySample = 1:10000)
i <- i + 1
if(i >= 10){
break
}
}
totalTime <- Sys.time() - startTime
print(totalTime)
## Time difference of 6.775087 secs
repeat
pruebaTiempo <- microbenchmark(
"codigo01_100" = guessNumber(mySample = 1:100),
"codigo01_1000" = guessNumber(mySample = 1:1000),
"codigo01_10000" = guessNumber(mySample = 1:10000),
"codigo02_100" = guessNumber2(mySample = 1:100),
"codigo02_1000" = guessNumber2(mySample = 1:1000),
"codigo02_10000" = guessNumber2(mySample = 1:10000),
times = 100
)
print(pruebaTiempo)
## Unit: microseconds
## expr min lq mean median uq
## codigo01_100 117.123 1639.701 7428.349 5776.985 10081.349
## codigo01_1000 219.452 11872.582 55720.541 42890.745 81753.780
## codigo01_10000 935.463 124278.218 496601.759 280895.986 773756.559
## codigo02_100 65.202 1349.765 2699.375 2760.052 4211.845
## codigo02_1000 366.760 19433.857 36778.340 36333.001 55390.289
## codigo02_10000 20690.649 563851.406 941584.892 999181.056 1367622.747
## max neval
## 40456.702 100
## 536776.584 100
## 2007386.197 100
## 6168.799 100
## 74659.783 100
## 1659831.666 100
repeat
next
y break
break
Ya hemos visto la palabra clave break
que permite salir del bucle actual. Por ejemplo, si buscamos el primer dÃgito después de 111 que es divisible por 32:
myVars <- 111:1000
for(myVar in myVars){
if(myVar %% 32 == 0){
print(myVar)
break
}
}
## [1] 128
Mejor no usar for
:
(111:1000)[111:1000 %% 32 == 0][1]
## [1] 128
next
La palabra clave next permite pasar a la siguiente iteración de un bucle si se cumple una determinada condición. Por ejemplo, si queremos imprimir las letras del alfabeto sin las vocales:
for(myLetter in letters){
if(myLetter %in% c("a", "e", "i", "o", "u", "y")){
next
}
print(myLetter)
}
## [1] "b"
## [1] "c"
## [1] "d"
## [1] "f"
## [1] "g"
## [1] "h"
## [1] "j"
## [1] "k"
## [1] "l"
## [1] "m"
## [1] "n"
## [1] "p"
## [1] "q"
## [1] "r"
## [1] "s"
## [1] "t"
## [1] "v"
## [1] "w"
## [1] "x"
## [1] "z"
Mejor no usar for
:
letters[! letters %in% c("a", "e", "i", "o", "u", "y")]
## [1] "b" "c" "d" "f" "g" "h" "j" "k" "l" "m" "n" "p" "q" "r" "s" "t" "v"
## [18] "w" "x" "z"