Bucles y estructuras de control en R

Bucles for y while, funciones de tipo *PPLY y funciones

1 Bucles en R

Las bucles permiten repetir operaciones y cambiar algunos valores en el proceso.

El tipo de bucle más utilizado es for:

for (i in 1:10)
{
  if(i%%2 ==0){cat(i,"es un número par\n")}else{print(i)}
}
[1] 1
2 es un número par
[1] 3
4 es un número par
[1] 5
6 es un número par
[1] 7
8 es un número par
[1] 9
10 es un número par

Tambien se puede utilizar while (principalmente útil cuando no se puede determinar el numero de operaciones, porque depende de lo que van a hacer las operaciones).

res<-1
while(res<10){
  add<-sample(c(1,2,3),1)
  res<-res+add
  cat("yo añado",add,"ahora 'res' vale",res,"\n")
}
yo añado 2 ahora 'res' vale 3 
yo añado 3 ahora 'res' vale 6 
yo añado 2 ahora 'res' vale 8 
yo añado 1 ahora 'res' vale 9 
yo añado 2 ahora 'res' vale 11 

2 Funciones *PPLY

Las funciones de tipo *PPLY permiten aplicar implícitamente una función en una bucle for sobre un objeto.

2.1 apply

apply aplica una función sobre una dimensión de un array (1 significa por fila, 2 por columna)

(load("../Datos/bog_chinga.RData"))
[1] "df_bog_chinga"  "mat_bog_chinga"
mat_bog_chinga
         Canis lupus Felis catus Tramarctos ornatus
Bogotá          3000        1000                  0
Chingaza         100           0                 50
         Odocoileus viginianus
Bogotá                       0
Chingaza                   200
apply(mat_bog_chinga,1,mean)
  Bogotá Chingaza 
  1000.0     87.5 
apply(mat_bog_chinga,2,mean)
          Canis lupus           Felis catus    Tramarctos ornatus 
                 1550                   500                    25 
Odocoileus viginianus 
                  100 

Cuando simplify está verdadero y que los objetos de resultados tienen las mismas dimensiones, apply intenta simplificar los objetos en vectores o arrays, cuando no se puede, o simplify es falso, entonces, envia una lista:

apply(mat_bog_chinga,1,mean,simplify = F)
$Bogotá
[1] 1000

$Chingaza
[1] 87.5

Las funciones se pueden definir directamente en la función apply, y los argumentos de las funciones se pueden poner en los argumentos de apply (las demás funciones de tipo *PPLY tambien lo aceptan:

apply(mat_bog_chinga,1,function(x,a)toupper(a[which.max(x)]),a=colnames(mat_bog_chinga))
                 Bogotá                Chingaza 
          "CANIS LUPUS" "ODOCOILEUS VIGINIANUS" 

2.2 lapply y sapply

lapply y sapply aplican la función a todos los elementos de un vector (y entonces a todos los elemetos de una lista). sapply simplifica el resultado si es posible

require(openxlsx)
cursoWB<-loadWorkbook("../Datos/Curso.xlsx")
contenidoPestañas <- lapply(names(cursoWB), read.xlsx, xlsxFile = cursoWB)
lapply(contenidoPestañas,dim)
[[1]]
[1] 10  3

[[2]]
[1] 20  1
sapply(contenidoPestañas,dim)
     [,1] [,2]
[1,]   10   20
[2,]    3    1

2.3 Reduce

En asociación con lapply, Reduce puede ser muy util para simplificar el resultado de manera diferente. Reduce toma una lista y aplica una funcion entre sus elementos para reducir el objeto

(totalRowCol<- Reduce(`+`,lapply(contenidoPestañas,dim)))
[1] 30  4
(totalRowCol<- Reduce(`rbind`,lapply(contenidoPestañas,dim)))
     [,1] [,2]
init   10    3
       20    1

2.4 tapply

tapply permite aplicar una función en un vector en función de grupos definidos en otro vector:

(valores <- 1:5)
[1] 1 2 3 4 5
(grupos <- as.factor(c(rep("A",3),rep("B",2))))
[1] A A A B B
Levels: A B
tapply(valores,grupos,sum)
A B 
6 9 

2.5 by

by es el equivalente de tapply para aplicar una función a una tabla según un vector de grupos:

(misViajes <- data.frame(pais=c("Francia","Colombia","Colombia","Chile"),
                        año=c(2021,2003,2004,2023)))
      pais  año
1  Francia 2021
2 Colombia 2003
3 Colombia 2004
4    Chile 2023
by(misViajes,misViajes$pais,function(x) paste(nrow(x),"viajes:",paste(x$año,sep="",collapse=", ")))
misViajes$pais: Chile
[1] "1 viajes: 2023"
---------------------------------------------------- 
misViajes$pais: Colombia
[1] "2 viajes: 2003, 2004"
---------------------------------------------------- 
misViajes$pais: Francia
[1] "1 viajes: 2021"

3 Crear funciones

En R, se pueden definir funciones utilizando function

Los argumentos se definen en las paréntesis, y pueden tener valor por defecto:

create_list_metaData<-function(date=Sys.Date(),tipoOrganismos,lugar="Concepción, Chile")
{
  return(list(date=date,tipoOrganismos=tipoOrganismos,lugar=lugar))
}
create_list_metaData(tipoOrganismos = "Plantas")
$date
[1] "2023-12-11"

$tipoOrganismos
[1] "Plantas"

$lugar
[1] "Concepción, Chile"
create_list_metaData(date=Sys.Date()+1, tipoOrganismos = "Animales")
$date
[1] "2023-12-12"

$tipoOrganismos
[1] "Animales"

$lugar
[1] "Concepción, Chile"

Una posibilidad interesante en las funciones es utilizar el argumento “…” para pasar argumentos no definidos a otra función.

max_mas1<-function(x,...)
{
  a<-max(x,...)
  return(a+1)
}

max_mas1(c(6,7,9))
[1] 10
max_mas1(c(6,7,9,NA))
[1] NA
max_mas1(c(6,7,9,NA),na.rm=T)
[1] 10