CC BY-NC-ND 3.0
ififSI [esto] ENTONCES [esto] SINO [esto]
myVar <- 2
if(myVar < 3){
print("myVar < 3")
}else{
print("myVar > 3")
}## [1] "myVar < 3"
ifmyVar <- 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"
ifif 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!"
ifif 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)!")
}ifprueba <- c(TRUE, FALSE, FALSE)
if(prueba[1] == TRUE &
prueba[2] == TRUE &
prueba[3] == TRUE){
print("¡SI!")
}ifprueba <- c(TRUE, FALSE, FALSE)
if(sum(prueba == TRUE) == length(prueba)){
print("¡SI!")
}ifprueba <- 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")
}switchswitchmiNombre <- "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"
switchmiNombre <- "Pablo"
switch(miNombre,
Alexa = result <- "Hola Alexa",
Juan = result <- "Hola Juan",
Pablo = result <- "Hola Pablo",
Javier = result <- "Hola Javier")
print(result)## [1] "Hola Pablo"
forforbdd <- 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
forfor (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
forletras <- 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
forletras <- 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().
whilewhilei <- 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.
whileEl 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.
whilemyNumber <- 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"
whilestartTime <- Sys.time()
print(startTime)## [1] "2019-02-15 12:37:12 CET"
whileprint(Sys.time() - startTime)## Time difference of 0.06940413 secs
whilerepeticiones <- 0
startTime <- Sys.time()
while(Sys.time() - startTime < 0.5){
repeticiones <- repeticiones + 1
}
print(repeticiones)## [1] 10565
whilerepeticiones <- 0
startTime <- Sys.time()
while(Sys.time() - startTime < 0.5){
repeticiones <- repeticiones + 1
if(repeticiones >= 1000){
break
}
}
print(repeticiones)## [1] 1000
whilemyNumber <- 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"
whileguessNumber <- 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
whileguessNumber <- 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
whileguessNumber2 <- 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
repeatrepeati <- 1
repeat{
print(i)
i <- i + 1
if(i >= 5){
break
}
}## [1] 1
## [1] 2
## [1] 3
## [1] 4
repeatstartTime <- 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
repeatstartTime <- 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
repeatpruebaTiempo <- 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
repeatnext y breakbreakYa 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
nextLa 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"