6 Iteração e controle de fluxo

6.1 Funções da família apply()

Algumas funções da família apply() são muito úteis na manipulação de dados e descrição de dados. Essas funções são muito poderosas, porque permitem você fazer iterações de forma simples, ou seja, você pode aplicar uma função a vários objetos simultaneamente com funções dessa família. O que você faz com essas funções você também faz com as iterações que fazem uso da expressão for(){} (veja seção 6.3), mas essas funções simplificam e aceleram o processo.

6.1.1 Em uma matriz

A função apply() poderia ser traduzida como:

aplique uma função (FUN) a todas as linhas ou colunas (MARGIN) de uma matriz (X):

?apply # Veja o help
# os argumentos dessa função são:
# X = matrix
# MAGRIN = 1 indica linha, 2 indica colunas
# FUN = a função que você deseja aplicar
# ... ARGUMENTOS DESSA FUNCAO SE FOR O CASO

# TOTAIS MARGINAIS
# crie uma matriz
X <- matrix(1:36, nrow = 4, ncol = 9)
colnames(X) <- paste("col", 1:ncol(X))
rownames(X) <- paste("ln", 1:nrow(X))
head(X) # cabeça da matriz criada
col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9
ln 1 1 5 9 13 17 21 25 29 33
ln 2 2 6 10 14 18 22 26 30 34
ln 3 3 7 11 15 19 23 27 31 35
ln 4 4 8 12 16 20 24 28 32 36
# calcule para todas as linhas:
# a soma dos valores
apply(X, MARGIN = 1, FUN = sum)
## ln 1 ln 2 ln 3 ln 4 
##  153  162  171  180
# o valor máximo
apply(X, MARGIN = 1, FUN = max)
## ln 1 ln 2 ln 3 ln 4 
##   33   34   35   36
# a média
apply(X, MARGIN = 1, FUN = mean)
## ln 1 ln 2 ln 3 ln 4 
##   17   18   19   20
# o desvio padrão
apply(X, MARGIN = 1, FUN = sd)
##     ln 1     ln 2     ln 3     ln 4 
## 10.95445 10.95445 10.95445 10.95445
# para todas as colunas
# a soma dos valores
apply(X, MARGIN = 2, FUN = sum)
## col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 
##    10    26    42    58    74    90   106   122   138
# o valor máximo
apply(X, MARGIN = 2, FUN = max)
## col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 
##     4     8    12    16    20    24    28    32    36
# a média
apply(X, MARGIN = 2, FUN = mean)
## col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 
##   2.5   6.5  10.5  14.5  18.5  22.5  26.5  30.5  34.5
# o desvio padrão
apply(X, MARGIN = 2, FUN = sd)
##    col 1    col 2    col 3    col 4    col 5    col 6    col 7    col 8 
## 1.290994 1.290994 1.290994 1.290994 1.290994 1.290994 1.290994 1.290994 
##    col 9 
## 1.290994

As funções rowSums(), rowMeans(), colSums(), ou colMeans() são equivalentes à função apply(). Elas simplificam o uso para somas (em inglês, sum) e médias (em inglês, mean) de linhas (em inglês, rows) e colunas (em inglês, columns). Se você conhece bem a função apply(), você pode fazer o que essas funções fazem e muito mais. Portanto, ao dominar a função apply(), você acaba por não precisar se preocupar em aprender essas funções mais específicas.

?rowSums
rowSums(X) # soma de cada linha
## ln 1 ln 2 ln 3 ln 4 
##  153  162  171  180
rowMeans(X) # media de cada linha
## ln 1 ln 2 ln 3 ln 4 
##   17   18   19   20
colSums(X) # soma de cada coluna
## col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 
##    10    26    42    58    74    90   106   122   138
colMeans(X) # média de cada coluna
## col 1 col 2 col 3 col 4 col 5 col 6 col 7 col 8 col 9 
##   2.5   6.5  10.5  14.5  18.5  22.5  26.5  30.5  34.5

6.1.2 Em um vetor ou lista

A função lapply() aplica uma função FUN para cada elemento de um vetor ou de uma lista, e retorna um objeto de classe list.

# muito simples, imprime algo linha por linha
ll <- lapply(LETTERS, print)
## [1] "A"
## [1] "B"
## [1] "C"
## [1] "D"
## [1] "E"
## [1] "F"
## [1] "G"
## [1] "H"
## [1] "I"
## [1] "J"
## [1] "K"
## [1] "L"
## [1] "M"
## [1] "N"
## [1] "O"
## [1] "P"
## [1] "Q"
## [1] "R"
## [1] "S"
## [1] "T"
## [1] "U"
## [1] "V"
## [1] "W"
## [1] "X"
## [1] "Y"
## [1] "Z"
class(ll)
## [1] "list"
str(ll)
## List of 26
##  $ : chr "A"
##  $ : chr "B"
##  $ : chr "C"
##  $ : chr "D"
##  $ : chr "E"
##  $ : chr "F"
##  $ : chr "G"
##  $ : chr "H"
##  $ : chr "I"
##  $ : chr "J"
##  $ : chr "K"
##  $ : chr "L"
##  $ : chr "M"
##  $ : chr "N"
##  $ : chr "O"
##  $ : chr "P"
##  $ : chr "Q"
##  $ : chr "R"
##  $ : chr "S"
##  $ : chr "T"
##  $ : chr "U"
##  $ : chr "V"
##  $ : chr "W"
##  $ : chr "X"
##  $ : chr "Y"
##  $ : chr "Z"
# suponha três vetores de tamanhos diferentes
v1 <- sample(1:1000, 50)
length(v1)
## [1] 50
v2 <- sample(1:100, 30)
length(v2)
## [1] 30
v3 <- sample(1000:2000, 90)
length(v3)
## [1] 90
# imagina que isso esteja numa lista
ml <- list(v1, v2, v3)
class(ml)
## [1] "list"
length(ml)
## [1] 3
# posso usar lapply para calcular a media desses vetores
lapply(ml, mean) # note que retorna uma lista
## [[1]]
## [1] 525.68
## 
## [[2]]
## [1] 41.66667
## 
## [[3]]
## [1] 1481.744
lt <- lapply(ml, mean) # podemos guardar
lt <- as.vector(lt, mode = "numeric") # e transformar num vetor. MODE neste caso é fundamental usar
lt
## [1]  525.68000   41.66667 1481.74444

6.1.3 Por categoria de um fator

A função tapply() aplica uma função FUN em uma coluna numérica individualizando os resultados para cada categoria de um determinado fator.

# vamos usar os dados de Iris novamente
?iris
# calculando o comprimento médio de sepálas pelas categorias de um fator (especies)
class(iris$Sepal.Length) # variavel numerica
## [1] "numeric"
class(iris$Species) # fator com categorias que correspondem a especies
## [1] "factor"
tapply(iris$Sepal.Length, iris$Species, FUN = mean)
##     setosa versicolor  virginica 
##      5.006      5.936      6.588
# calculando o comprimento máximo por especie
tapply(iris$Sepal.Length, iris$Species, FUN = max)
##     setosa versicolor  virginica 
##        5.8        7.0        7.9
# a amplitude de variacao
tapply(iris$Sepal.Length, iris$Species, FUN = range)
## $setosa
## [1] 4.3 5.8
## 
## $versicolor
## [1] 4.9 7.0
## 
## $virginica
## [1] 4.9 7.9
# note que essa funcao sempre retorna um array (que é uma lista de fato, neste caso)
tm <- tapply(iris$Sepal.Length, iris$Species, FUN = min)
class(tm)
## [1] "array"
names(tm)
## [1] "setosa"     "versicolor" "virginica"
tm[["setosa"]] # indexadores de lista
## [1] 4.3
tr <- tapply(iris$Sepal.Length, iris$Species, FUN = range)
class(tr)
## [1] "array"
names(tr)
## [1] "setosa"     "versicolor" "virginica"
tr[["setosa"]]
## [1] 4.3 5.8

6.2 Condicionais

Condicionais são expressões que permitem a um programa a tomada de decisões. Vamos tratar aqui das condicionais if (), if () else {}, e ifelse () (veja a seção Para saber mais para mais informações).

6.2.1 Condicional if ()

A expressão if () avalia um vetor atômico (ou de índice 1) lógico e executa o que estiver entre {} se o valor do vetor for verdadeiro (TRUE).

A estrutura básica de um if () é:

if (condicao) {
  
  ação a ser realizada caso a condição seja VERDADEIRA
}

Dentro do par de parênteses, deve haver uma condição. Condições em R são feitas com operadores lógicos: ==, !=, >, < etc (veja a seção @ref(#vetor-operador-logico) para relembrar; veja também a seção Para saber mais pois apresenta links para vídeoaulas importantes).

6.2.1.1 Exemplo 01

perdiz_estuda_breu <- TRUE
perdiz_estuda_grama <- FALSE
perdiz_estuda_breu
## [1] TRUE
perdiz_estuda_grama
## [1] FALSE
if (perdiz_estuda_breu) {
  print("Breu pode ser Protium, Dacryodes, Trattinnickia, e é da família Burseraceae")
}
## [1] "Breu pode ser Protium, Dacryodes, Trattinnickia, e é da família Burseraceae"
if (perdiz_estuda_grama) {
  print("Isso não vai dar imprimir")
}

Reparem na condição que deve ser satisfeita dentro dos parênteses: TRUE, para efetuar a ação; se FALSE, não executa a função:

if (TRUE) {
  print("Eu executo!")
}
## [1] "Eu executo!"
if (FALSE) {
  print("Eu não executo")
}

6.2.2 Condicional if () com o else

A condicional if () pode ser expandida para if () { } else {}: execute em {} se if () for VERDADEIRO, caso contrário (== else), execute o que estiver entre o segundo par {}.

6.2.2.1 Exemplo 01

meunumero <- 77
meunumero
## [1] 77
if (meunumero == 76) {
  print("Meu número é o 3")
} else {

  # meu_else <- paste0("Mas pode ser o ", meunumero)
  # print(meu_else)
  # 1+1
  print(paste("Se eu somar o meu número ", meunumero, "com 3, eu vou obter ", meunumero + 3))
}
## [1] "Se eu somar o meu número  77 com 3, eu vou obter  80"

6.2.2.2 Exemplo 02

familia <- c("Burseraceae", "Solanaceae", "Sapindaceae", "Rubiaceae")
clado <- c("Malvids", "Lamiids", "Malvids", "Lamiids")
apg <- data.frame(familia = familia, clado = clado, stringsAsFactors = FALSE)
apg
familia clado
Burseraceae Malvids
Solanaceae Lamiids
Sapindaceae Malvids
Rubiaceae Lamiids
str(apg)
## 'data.frame':    4 obs. of  2 variables:
##  $ familia: chr  "Burseraceae" "Solanaceae" "Sapindaceae" "Rubiaceae"
##  $ clado  : chr  "Malvids" "Lamiids" "Malvids" "Lamiids"
dim(apg)
## [1] 4 2
malvids <- c("Burseraceae", "Sapindaceae")

meunumero <- 4
apg$familia[meunumero]
## [1] "Rubiaceae"
apg$familia[meunumero] %in% malvids
## [1] FALSE
if (apg$familia[meunumero] %in% malvids) {
  malv_fam <- paste(malvids, collapse = " e ")
  malv_fam
  clado <- "Malvids"
  frase <- paste(malv_fam, clado, sep = " pertencem ao clado das ")
  frase
  print(frase)
} else {
  paste("A família", apg$familia[meunumero], "pertence ao clado das", apg$clado[meunumero])
}
## [1] "A família Rubiaceae pertence ao clado das Lamiids"

6.2.3 Condicional ifelse()

ifelse(condicao, executa se VERDADEIRO, executa se FALSO)
set.seed(333)
familia
## [1] "Burseraceae" "Solanaceae"  "Sapindaceae" "Rubiaceae"
familias <- sample(familia, 100, replace = TRUE)
familias
##   [1] "Solanaceae"  "Burseraceae" "Sapindaceae" "Solanaceae"  "Sapindaceae"
##   [6] "Rubiaceae"   "Solanaceae"  "Solanaceae"  "Sapindaceae" "Rubiaceae"  
##  [11] "Sapindaceae" "Sapindaceae" "Rubiaceae"   "Sapindaceae" "Burseraceae"
##  [16] "Sapindaceae" "Sapindaceae" "Solanaceae"  "Sapindaceae" "Solanaceae" 
##  [21] "Burseraceae" "Solanaceae"  "Rubiaceae"   "Solanaceae"  "Sapindaceae"
##  [26] "Burseraceae" "Solanaceae"  "Sapindaceae" "Solanaceae"  "Rubiaceae"  
##  [31] "Solanaceae"  "Sapindaceae" "Burseraceae" "Solanaceae"  "Rubiaceae"  
##  [36] "Burseraceae" "Solanaceae"  "Solanaceae"  "Rubiaceae"   "Rubiaceae"  
##  [41] "Burseraceae" "Burseraceae" "Burseraceae" "Burseraceae" "Sapindaceae"
##  [46] "Burseraceae" "Solanaceae"  "Burseraceae" "Rubiaceae"   "Burseraceae"
##  [51] "Sapindaceae" "Burseraceae" "Sapindaceae" "Burseraceae" "Sapindaceae"
##  [56] "Rubiaceae"   "Rubiaceae"   "Rubiaceae"   "Rubiaceae"   "Solanaceae" 
##  [61] "Burseraceae" "Solanaceae"  "Burseraceae" "Sapindaceae" "Burseraceae"
##  [66] "Burseraceae" "Rubiaceae"   "Sapindaceae" "Solanaceae"  "Solanaceae" 
##  [71] "Rubiaceae"   "Solanaceae"  "Sapindaceae" "Burseraceae" "Rubiaceae"  
##  [76] "Solanaceae"  "Solanaceae"  "Burseraceae" "Burseraceae" "Sapindaceae"
##  [81] "Solanaceae"  "Sapindaceae" "Sapindaceae" "Burseraceae" "Sapindaceae"
##  [86] "Rubiaceae"   "Burseraceae" "Sapindaceae" "Solanaceae"  "Rubiaceae"  
##  [91] "Solanaceae"  "Solanaceae"  "Burseraceae" "Solanaceae"  "Burseraceae"
##  [96] "Burseraceae" "Solanaceae"  "Solanaceae"  "Sapindaceae" "Solanaceae"
table(familias)
Burseraceae Rubiaceae Sapindaceae Solanaceae
27 18 25 30
familias
##   [1] "Solanaceae"  "Burseraceae" "Sapindaceae" "Solanaceae"  "Sapindaceae"
##   [6] "Rubiaceae"   "Solanaceae"  "Solanaceae"  "Sapindaceae" "Rubiaceae"  
##  [11] "Sapindaceae" "Sapindaceae" "Rubiaceae"   "Sapindaceae" "Burseraceae"
##  [16] "Sapindaceae" "Sapindaceae" "Solanaceae"  "Sapindaceae" "Solanaceae" 
##  [21] "Burseraceae" "Solanaceae"  "Rubiaceae"   "Solanaceae"  "Sapindaceae"
##  [26] "Burseraceae" "Solanaceae"  "Sapindaceae" "Solanaceae"  "Rubiaceae"  
##  [31] "Solanaceae"  "Sapindaceae" "Burseraceae" "Solanaceae"  "Rubiaceae"  
##  [36] "Burseraceae" "Solanaceae"  "Solanaceae"  "Rubiaceae"   "Rubiaceae"  
##  [41] "Burseraceae" "Burseraceae" "Burseraceae" "Burseraceae" "Sapindaceae"
##  [46] "Burseraceae" "Solanaceae"  "Burseraceae" "Rubiaceae"   "Burseraceae"
##  [51] "Sapindaceae" "Burseraceae" "Sapindaceae" "Burseraceae" "Sapindaceae"
##  [56] "Rubiaceae"   "Rubiaceae"   "Rubiaceae"   "Rubiaceae"   "Solanaceae" 
##  [61] "Burseraceae" "Solanaceae"  "Burseraceae" "Sapindaceae" "Burseraceae"
##  [66] "Burseraceae" "Rubiaceae"   "Sapindaceae" "Solanaceae"  "Solanaceae" 
##  [71] "Rubiaceae"   "Solanaceae"  "Sapindaceae" "Burseraceae" "Rubiaceae"  
##  [76] "Solanaceae"  "Solanaceae"  "Burseraceae" "Burseraceae" "Sapindaceae"
##  [81] "Solanaceae"  "Sapindaceae" "Sapindaceae" "Burseraceae" "Sapindaceae"
##  [86] "Rubiaceae"   "Burseraceae" "Sapindaceae" "Solanaceae"  "Rubiaceae"  
##  [91] "Solanaceae"  "Solanaceae"  "Burseraceae" "Solanaceae"  "Burseraceae"
##  [96] "Burseraceae" "Solanaceae"  "Solanaceae"  "Sapindaceae" "Solanaceae"
ifelse(familias == "Burseraceae", TRUE, FALSE)
##   [1] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [13] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
##  [25] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE
##  [37] FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE
##  [49] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61]  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73] FALSE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE
##  [85] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE
##  [97] FALSE FALSE FALSE FALSE
ifelse(familias == "Sapindaceae", "Sapindaceae é a família do guaraná", "Não é Sapindaceae")
##   [1] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##   [3] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##   [5] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##   [7] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##   [9] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [11] "Sapindaceae é a família do guaraná" "Sapindaceae é a família do guaraná"
##  [13] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [15] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [17] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [19] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [21] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [23] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [25] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [27] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [29] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [31] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [33] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [35] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [37] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [39] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [41] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [43] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [45] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [47] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [49] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [51] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [53] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [55] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [57] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [59] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [61] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [63] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [65] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [67] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [69] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [71] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [73] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [75] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [77] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [79] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [81] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [83] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [85] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"                 
##  [87] "Não é Sapindaceae"                  "Sapindaceae é a família do guaraná"
##  [89] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [91] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [93] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [95] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [97] "Não é Sapindaceae"                  "Não é Sapindaceae"                 
##  [99] "Sapindaceae é a família do guaraná" "Não é Sapindaceae"
familias[3]
## [1] "Sapindaceae"
familias[1:10]
##  [1] "Solanaceae"  "Burseraceae" "Sapindaceae" "Solanaceae"  "Sapindaceae"
##  [6] "Rubiaceae"   "Solanaceae"  "Solanaceae"  "Sapindaceae" "Rubiaceae"
ifelse(familias == "Sapindaceae", "Sapindaceae da ordem Sapindales",
  ifelse(familias == "Burseraceae", "Burseraceae também é da ordem Sapindales", "Nenhuma dessas famílias é uma Sapindales")
)
##   [1] "Nenhuma dessas famílias é uma Sapindales"
##   [2] "Burseraceae também é da ordem Sapindales"
##   [3] "Sapindaceae da ordem Sapindales"         
##   [4] "Nenhuma dessas famílias é uma Sapindales"
##   [5] "Sapindaceae da ordem Sapindales"         
##   [6] "Nenhuma dessas famílias é uma Sapindales"
##   [7] "Nenhuma dessas famílias é uma Sapindales"
##   [8] "Nenhuma dessas famílias é uma Sapindales"
##   [9] "Sapindaceae da ordem Sapindales"         
##  [10] "Nenhuma dessas famílias é uma Sapindales"
##  [11] "Sapindaceae da ordem Sapindales"         
##  [12] "Sapindaceae da ordem Sapindales"         
##  [13] "Nenhuma dessas famílias é uma Sapindales"
##  [14] "Sapindaceae da ordem Sapindales"         
##  [15] "Burseraceae também é da ordem Sapindales"
##  [16] "Sapindaceae da ordem Sapindales"         
##  [17] "Sapindaceae da ordem Sapindales"         
##  [18] "Nenhuma dessas famílias é uma Sapindales"
##  [19] "Sapindaceae da ordem Sapindales"         
##  [20] "Nenhuma dessas famílias é uma Sapindales"
##  [21] "Burseraceae também é da ordem Sapindales"
##  [22] "Nenhuma dessas famílias é uma Sapindales"
##  [23] "Nenhuma dessas famílias é uma Sapindales"
##  [24] "Nenhuma dessas famílias é uma Sapindales"
##  [25] "Sapindaceae da ordem Sapindales"         
##  [26] "Burseraceae também é da ordem Sapindales"
##  [27] "Nenhuma dessas famílias é uma Sapindales"
##  [28] "Sapindaceae da ordem Sapindales"         
##  [29] "Nenhuma dessas famílias é uma Sapindales"
##  [30] "Nenhuma dessas famílias é uma Sapindales"
##  [31] "Nenhuma dessas famílias é uma Sapindales"
##  [32] "Sapindaceae da ordem Sapindales"         
##  [33] "Burseraceae também é da ordem Sapindales"
##  [34] "Nenhuma dessas famílias é uma Sapindales"
##  [35] "Nenhuma dessas famílias é uma Sapindales"
##  [36] "Burseraceae também é da ordem Sapindales"
##  [37] "Nenhuma dessas famílias é uma Sapindales"
##  [38] "Nenhuma dessas famílias é uma Sapindales"
##  [39] "Nenhuma dessas famílias é uma Sapindales"
##  [40] "Nenhuma dessas famílias é uma Sapindales"
##  [41] "Burseraceae também é da ordem Sapindales"
##  [42] "Burseraceae também é da ordem Sapindales"
##  [43] "Burseraceae também é da ordem Sapindales"
##  [44] "Burseraceae também é da ordem Sapindales"
##  [45] "Sapindaceae da ordem Sapindales"         
##  [46] "Burseraceae também é da ordem Sapindales"
##  [47] "Nenhuma dessas famílias é uma Sapindales"
##  [48] "Burseraceae também é da ordem Sapindales"
##  [49] "Nenhuma dessas famílias é uma Sapindales"
##  [50] "Burseraceae também é da ordem Sapindales"
##  [51] "Sapindaceae da ordem Sapindales"         
##  [52] "Burseraceae também é da ordem Sapindales"
##  [53] "Sapindaceae da ordem Sapindales"         
##  [54] "Burseraceae também é da ordem Sapindales"
##  [55] "Sapindaceae da ordem Sapindales"         
##  [56] "Nenhuma dessas famílias é uma Sapindales"
##  [57] "Nenhuma dessas famílias é uma Sapindales"
##  [58] "Nenhuma dessas famílias é uma Sapindales"
##  [59] "Nenhuma dessas famílias é uma Sapindales"
##  [60] "Nenhuma dessas famílias é uma Sapindales"
##  [61] "Burseraceae também é da ordem Sapindales"
##  [62] "Nenhuma dessas famílias é uma Sapindales"
##  [63] "Burseraceae também é da ordem Sapindales"
##  [64] "Sapindaceae da ordem Sapindales"         
##  [65] "Burseraceae também é da ordem Sapindales"
##  [66] "Burseraceae também é da ordem Sapindales"
##  [67] "Nenhuma dessas famílias é uma Sapindales"
##  [68] "Sapindaceae da ordem Sapindales"         
##  [69] "Nenhuma dessas famílias é uma Sapindales"
##  [70] "Nenhuma dessas famílias é uma Sapindales"
##  [71] "Nenhuma dessas famílias é uma Sapindales"
##  [72] "Nenhuma dessas famílias é uma Sapindales"
##  [73] "Sapindaceae da ordem Sapindales"         
##  [74] "Burseraceae também é da ordem Sapindales"
##  [75] "Nenhuma dessas famílias é uma Sapindales"
##  [76] "Nenhuma dessas famílias é uma Sapindales"
##  [77] "Nenhuma dessas famílias é uma Sapindales"
##  [78] "Burseraceae também é da ordem Sapindales"
##  [79] "Burseraceae também é da ordem Sapindales"
##  [80] "Sapindaceae da ordem Sapindales"         
##  [81] "Nenhuma dessas famílias é uma Sapindales"
##  [82] "Sapindaceae da ordem Sapindales"         
##  [83] "Sapindaceae da ordem Sapindales"         
##  [84] "Burseraceae também é da ordem Sapindales"
##  [85] "Sapindaceae da ordem Sapindales"         
##  [86] "Nenhuma dessas famílias é uma Sapindales"
##  [87] "Burseraceae também é da ordem Sapindales"
##  [88] "Sapindaceae da ordem Sapindales"         
##  [89] "Nenhuma dessas famílias é uma Sapindales"
##  [90] "Nenhuma dessas famílias é uma Sapindales"
##  [91] "Nenhuma dessas famílias é uma Sapindales"
##  [92] "Nenhuma dessas famílias é uma Sapindales"
##  [93] "Burseraceae também é da ordem Sapindales"
##  [94] "Nenhuma dessas famílias é uma Sapindales"
##  [95] "Burseraceae também é da ordem Sapindales"
##  [96] "Burseraceae também é da ordem Sapindales"
##  [97] "Nenhuma dessas famílias é uma Sapindales"
##  [98] "Nenhuma dessas famílias é uma Sapindales"
##  [99] "Sapindaceae da ordem Sapindales"         
## [100] "Nenhuma dessas famílias é uma Sapindales"
sei_qual_ordem <- ifelse(familias == "Sapindaceae", "Sapindaceae da ordem Sapindales",
  ifelse(familias == "Burseraceae", "Burseraceae também é da ordem Sapindales", "Nenhuma dessas famílias é uma Sapindales")
)

meudf <- data.frame(familias, sei_qual_ordem)
meudf
familias sei_qual_ordem
Solanaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Rubiaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Burseraceae Burseraceae também é da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales
Sapindaceae Sapindaceae da ordem Sapindales
Solanaceae Nenhuma dessas famílias é uma Sapindales

6.3 Iterações

Vocês usaram várias funções da família apply, especialmente apply() e tapply(), que são funções especiais que repetem uma mesma função FUN para cada objeto de um conjunto (vetores, matrizes, valores atômicos). Essas funções utilizam portanto a lógica de iterações (em inglês, loops), ou seja, fazem a mesma ação repetidas vezes; em outras palavras, fazem LOOPs, dão voltas, realizam o mesmo percurso várias vezes, percorrem um circuito.

As expressões for(){} e while(){} permitem fazer LOOPs, e LOOPs dentro de LOOPS com muita liberdade. Aprendê-las é o mesmo que aprender todas as funções da família apply juntas (apply(), tapply(), sapply(), lapply(), mapply() etc). Se você compreende os LOOPS, pode fazer o que essas funções fazem sem precisar delas (embora elas possam executar a tarefa mais rapidamente).

6.3.1 Iteração com for(){}

6.3.1.1 Exemplo 1

Um exemplo simples do que seria uma iteração com o comando for(){}:

# vamos imprimir na tela as letras do objeto LETTERS
for (let in 1:length(LETTERS)) {
  paraimprimir <- paste(LETTERS[let], " é a letra de índice ", let)
  print(paraimprimir)
}
## [1] "A  é a letra de índice  1"
## [1] "B  é a letra de índice  2"
## [1] "C  é a letra de índice  3"
## [1] "D  é a letra de índice  4"
## [1] "E  é a letra de índice  5"
## [1] "F  é a letra de índice  6"
## [1] "G  é a letra de índice  7"
## [1] "H  é a letra de índice  8"
## [1] "I  é a letra de índice  9"
## [1] "J  é a letra de índice  10"
## [1] "K  é a letra de índice  11"
## [1] "L  é a letra de índice  12"
## [1] "M  é a letra de índice  13"
## [1] "N  é a letra de índice  14"
## [1] "O  é a letra de índice  15"
## [1] "P  é a letra de índice  16"
## [1] "Q  é a letra de índice  17"
## [1] "R  é a letra de índice  18"
## [1] "S  é a letra de índice  19"
## [1] "T  é a letra de índice  20"
## [1] "U  é a letra de índice  21"
## [1] "V  é a letra de índice  22"
## [1] "W  é a letra de índice  23"
## [1] "X  é a letra de índice  24"
## [1] "Y  é a letra de índice  25"
## [1] "Z  é a letra de índice  26"

Ou seja, para cada elemento do objeto let, assumindo os valores na sequência do elemento 1 ao elemento corresponden ao comprimento (== length(LETTERS)) do objeto LETTERS, execute o que está dentro de {}.

6.3.1.2 Exemplo 2

# Fazendo um loop com for(){} replicando o que a função apply() faz
# criamos uma matriz
vetn <- rnorm(100, 30, 1)
mvetn <- matrix(vetn, ncol = 10, dimnames = list(paste("linha", 1:10), paste("coluna", 1:10)))
head(mvetn)
coluna 1 coluna 2 coluna 3 coluna 4 coluna 5 coluna 6 coluna 7 coluna 8 coluna 9 coluna 10
linha 1 29.83293 29.14018 29.23649 30.41905 30.94899 29.84389 29.97366 30.15412 29.34273 30.08479
linha 2 31.24129 31.05689 29.45685 30.92010 30.28868 30.51557 29.74122 30.46949 28.15604 30.88475
linha 3 30.29010 31.34928 29.17843 28.80200 30.94568 29.34699 29.88953 28.76698 29.47358 29.82502
linha 4 29.94628 30.14674 30.23371 28.56894 31.47962 32.13595 29.62404 28.93148 30.15042 31.61015
linha 5 30.07430 30.81179 29.26558 29.58111 29.59002 29.91044 32.09775 31.96293 27.54644 30.83061
linha 6 29.88561 28.47641 29.62197 30.23359 29.96315 28.71014 30.48448 31.47933 30.73691 31.11348
# Fazendo algo == apply(mvetn,2,mean)
# cria um objeto para salvar o resultado
resultado <- NULL
for (coluna in 1:ncol(mvetn)) {
  # pega a coluna
  cl <- mvetn[, coluna]
  # calcula a media
  mcl <- mean(cl)
  print(paste("Média da coluna", colnames(mvetn)[cl], "=", round(mcl, 2)))
  # salva o resultado com a media do item anterior
  resultado <- c(resultado, mcl)
}
##  [1] "Média da coluna NA = 30.02" "Média da coluna NA = 30.02"
##  [3] "Média da coluna NA = 30.02" "Média da coluna NA = 30.02"
##  [5] "Média da coluna NA = 30.02" "Média da coluna NA = 30.02"
##  [7] "Média da coluna NA = 30.02" "Média da coluna NA = 30.02"
##  [9] "Média da coluna NA = 30.02" "Média da coluna NA = 30.02"
##  [1] "Média da coluna NA = 29.77" "Média da coluna NA = 29.77"
##  [3] "Média da coluna NA = 29.77" "Média da coluna NA = 29.77"
##  [5] "Média da coluna NA = 29.77" "Média da coluna NA = 29.77"
##  [7] "Média da coluna NA = 29.77" "Média da coluna NA = 29.77"
##  [9] "Média da coluna NA = 29.77" "Média da coluna NA = 29.77"
##  [1] "Média da coluna NA = 29.92" "Média da coluna NA = 29.92"
##  [3] "Média da coluna NA = 29.92" "Média da coluna NA = 29.92"
##  [5] "Média da coluna NA = 29.92" "Média da coluna NA = 29.92"
##  [7] "Média da coluna NA = 29.92" "Média da coluna NA = 29.92"
##  [9] "Média da coluna NA = 29.92" "Média da coluna NA = 29.92"
##  [1] "Média da coluna NA = 29.8" "Média da coluna NA = 29.8"
##  [3] "Média da coluna NA = 29.8" "Média da coluna NA = 29.8"
##  [5] "Média da coluna NA = 29.8" "Média da coluna NA = 29.8"
##  [7] "Média da coluna NA = 29.8" "Média da coluna NA = 29.8"
##  [9] "Média da coluna NA = 29.8" "Média da coluna NA = 29.8"
##  [1] "Média da coluna NA = 30.21" "Média da coluna NA = 30.21"
##  [3] "Média da coluna NA = 30.21" "Média da coluna NA = 30.21"
##  [5] "Média da coluna NA = 30.21" "Média da coluna NA = 30.21"
##  [7] "Média da coluna NA = 30.21" "Média da coluna NA = 30.21"
##  [9] "Média da coluna NA = 30.21" "Média da coluna NA = 30.21"
##  [1] "Média da coluna NA = 29.85" "Média da coluna NA = 29.85"
##  [3] "Média da coluna NA = 29.85" "Média da coluna NA = 29.85"
##  [5] "Média da coluna NA = 29.85" "Média da coluna NA = 29.85"
##  [7] "Média da coluna NA = 29.85" "Média da coluna NA = 29.85"
##  [9] "Média da coluna NA = 29.85" "Média da coluna NA = 29.85"
##  [1] "Média da coluna NA = 30.34" "Média da coluna NA = 30.34"
##  [3] "Média da coluna NA = 30.34" "Média da coluna NA = 30.34"
##  [5] "Média da coluna NA = 30.34" "Média da coluna NA = 30.34"
##  [7] "Média da coluna NA = 30.34" "Média da coluna NA = 30.34"
##  [9] "Média da coluna NA = 30.34" "Média da coluna NA = 30.34"
##  [1] "Média da coluna NA = 30.33" "Média da coluna NA = 30.33"
##  [3] "Média da coluna NA = 30.33" "Média da coluna NA = 30.33"
##  [5] "Média da coluna NA = 30.33" "Média da coluna NA = 30.33"
##  [7] "Média da coluna NA = 30.33" "Média da coluna NA = 30.33"
##  [9] "Média da coluna NA = 30.33" "Média da coluna NA = 30.33"
##  [1] "Média da coluna NA = 29.95" "Média da coluna NA = 29.95"
##  [3] "Média da coluna NA = 29.95" "Média da coluna NA = 29.95"
##  [5] "Média da coluna NA = 29.95" "Média da coluna NA = 29.95"
##  [7] "Média da coluna NA = 29.95" "Média da coluna NA = 29.95"
##  [9] "Média da coluna NA = 29.95" "Média da coluna NA = 29.95"
##  [1] "Média da coluna NA = 30.69" "Média da coluna NA = 30.69"
##  [3] "Média da coluna NA = 30.69" "Média da coluna NA = 30.69"
##  [5] "Média da coluna NA = 30.69" "Média da coluna NA = 30.69"
##  [7] "Média da coluna NA = 30.69" "Média da coluna NA = 30.69"
##  [9] "Média da coluna NA = 30.69" "Média da coluna NA = 30.69"
# adicona o nome das colunas
names(resultado) <- colnames(mvetn)
# ver o resultado
resultado
##  coluna 1  coluna 2  coluna 3  coluna 4  coluna 5  coluna 6  coluna 7  coluna 8 
##  30.02231  29.76714  29.91783  29.79591  30.21034  29.85470  30.33654  30.32650 
##  coluna 9 coluna 10 
##  29.94533  30.69054
# identico ao apply, maior controle de como a média é aplicada
resultado == apply(mvetn, 2, mean)
##  coluna 1  coluna 2  coluna 3  coluna 4  coluna 5  coluna 6  coluna 7  coluna 8 
##      TRUE      TRUE      TRUE      TRUE      TRUE      TRUE      TRUE      TRUE 
##  coluna 9 coluna 10 
##      TRUE      TRUE

6.3.1.3 Exemplo 3

Agora usando for(){} para fazer algo como o tapply().

# Fazendo algo == tapply(mvetn[,2],mvetn$classe,sum)
# criamos uma matriz
vetn <- rnorm(100, 30, 1)
mvetn <- matrix(vetn, ncol = 10, dimnames = list(paste("linha", 1:10), paste("coluna", 1:10)))
# transformamos num data.frame adicionando uma coluna categorica
mvetn <- data.frame(classe = sample(paste("categ", 1:3, sep = ""), size = nrow(mvetn), replace = T), mvetn)
head(mvetn[, 1:5])
# cria um objeto para salvar o resultado
resultado <- NULL
# para cada categoria
for (ct in 1:length(levels(mvetn$classe))) {
  # pega a categoria
  cl <- levels(mvetn$classe)[ct]
  # filtra os dados (vetor logico)
  vl <- mvetn$classe == cl
  # calcula a soma dos dados da categoria
  soma <- sum(mvetn[vl, 2], na.rm = T)
  # imprime o passo
  print(paste("A soma da categoria", cl, " é igual a ", soma))
  # junta os resultados
  resultado <- c(resultado, soma)
}
# atribui nomes aos elementos do vetor de somas
names(resultado) <- levels(mvetn$classe)
# confere
resultado == tapply(mvetn[, 2], mvetn$classe, sum)

6.3.1.4 Exemplo 4

Calculando somas e médias de linhas, similar ao que podemos fazer com a função apply():

somas <- NULL # objeto vazio para salvar soma de cada linha
medias <- NULL # objeto vazio para salvar medias de cada linha
for (i in 1:nrow(X)) { # para cada linha
  somai <- sum(X[i, ]) # soma dos valores na linha i
  somas <- c(somas, somai) # junta a somai com o resto (que estará vazio na primeira vez)
  mediai <- mean(X[i, ]) # média  dos valores na linha i
  medias <- c(medias, mediai) # junta as medias
}
# como a matriz tem nomes, acrescenta esses nomes aos vetores com resultados
names(medias) <- rownames(X)
medias
## ln 1 ln 2 ln 3 ln 4 
##   17   18   19   20
names(somas) <- rownames(X)
somas
## ln 1 ln 2 ln 3 ln 4 
##  153  162  171  180

6.3.2 Iteração com while(){}

O comando while(){} funciona de forma parecida, mas faz algo ENQUANTO (em inglês, while) a condição em while(){} seja verdadeira. Um exemplo simples:

6.3.2.1 Exemplo 1

# cria um vetor de valores aleatorizados
vet <- sample(10:100)
# amostra um valor do vetor até que este valor seja 10
conta <- 1
valor <- 0
while (valor != 10) {
  valor <- sample(vet, 1)
  print(paste("o valor selecionado na iteração", conta, "foi de ", valor))
  conta <- conta + 1
}
## [1] "o valor selecionado na iteração 1 foi de  81"
## [1] "o valor selecionado na iteração 2 foi de  23"
## [1] "o valor selecionado na iteração 3 foi de  30"
## [1] "o valor selecionado na iteração 4 foi de  32"
## [1] "o valor selecionado na iteração 5 foi de  39"
## [1] "o valor selecionado na iteração 6 foi de  74"
## [1] "o valor selecionado na iteração 7 foi de  88"
## [1] "o valor selecionado na iteração 8 foi de  16"
## [1] "o valor selecionado na iteração 9 foi de  60"
## [1] "o valor selecionado na iteração 10 foi de  61"
## [1] "o valor selecionado na iteração 11 foi de  62"
## [1] "o valor selecionado na iteração 12 foi de  74"
## [1] "o valor selecionado na iteração 13 foi de  10"

6.3.3 Iteração com for(){} e a condicional if(){}

6.3.3.1 Exemplo 1

# cria um vetor de valores aleatorizados
vet <- sample(10:100, 60, replace = T)
# amostra um valor do vetor até que este valor seja 10
for (v in 1:10000) {
  valor <- sample(vet, 1)
  if (valor == 10) {
    # se o valor selecionado aleatoriamente for 10, ou seja se a expressão valor==10 for TRUE execute:
    # imprima isso
    print(paste("A primeira vez que o valor 10 foi selecionado aleatoriamente foi quando o objeto v assumiu o valor de", v))
    # interrompa (quebre) o loop
    break # note este argumento
  } else {
    # caso contrario, valor!=10, imprime o valor selecionado e continua o loop
    print(paste("O valor selecionado foi ", valor, "no indice", v))
  }
}

É possível que o script acima repita as 10000 vezes do for(){} sem encontrar o valor 10, até porque o 10 pode não estar em vet se não for amostrado.

6.4 Criando ou modificando funções

Funções são objetos que contêm um script que usa os argumentos (também objetos) para executar alguma coisa. A expressão function(){} é utilizada para criar funções. Criar funções é útil pois podem executar algo várias vezes (podendo ser de forma diferente) sem precisar reescrever o código todas às vezes. Isso nos auxilia em práticas rotineiras como, por exemplo, na manipulação de um conjunto de dados de localização geográfica de espécimes botânicos. Podemos gerar um mapa personalizado de distribuição geográfica de cada espécie criando uma função para plotar um mapa, e depois utilizamos a aplicamos a função sobre a categoria, neste caso, a variável contendo o nome da espécie. É muito útil também poder modificar uma função criada por outra pessoa, seja uma função de um determinado pacote ou uma função que você encontrou em uma página qualquer navegando pela internet.

É muito simples construir uma função. Há um bloco que deve ser sempre repetido:

function(meu_argumento1, meu_argumento2, ...) {
  
  # AQUI FICAM AS AÇÕES DE SUA FUNÇÃO, COMO POR EXEMPLO
  
  return("resultado da função") #
  
} 

É costume sempre utilizar a função return() como último elemento da função para que algum objeto seja retornado ao usuário.

?return # veja o help

6.4.1 Exemplo I

Vamos fazer a nossa versão da função mean(), que tira a média aritmética dos valores de um vetor.

# Vamos fazer essa função na unha:
amedia <- function(x) {
  # x será um vetor de comprimento >=1 e todos os valores devem ser numéricos, senão precisamos avisar.
  # essa funçao ira retornar o valor do 'am' que definimos como nulo inicialmente
  am <- NULL
  # condicao 1
  c1 <- is.vector(x)
  # condicao 2
  xx <- as.numeric(x) # convertemos em numérico
  xx <- xx[!is.na(xx)] # tira o que não é número (o que não foi convertido ou está em branco)
  c2 <- length(xx) == length(x) # os comprimentos são iguais? e tem algum valor?
  if (c1 & length(xx) > 0) { # se for um vetor e houver algum valor numérico, pode calcular a média
    am <- sum(xx) / length(xx)
    if (!c2) { # se c1 for falso
      print(paste(length(x) - length(xx), " valores do vetor não são numéricos e foram excluídos")) # avisa
    }
  } else {
    print("O objeto não é um vetor ou não há valores numéricos") # avisa
  }
  return(am)
}

Vamos agora utilizar a função:

v1 <- c(1, 2, 3, 4, 5, 6)
amedia(v1)
## [1] 3.5
v1 <- c(3, 3, 3, 3, 3, 3, 3)
amedia(v1)
## [1] 3
v1 <- c(3, 3, 3, 3, 3, 3, "A")
amedia(v1)
## Warning in amedia(v1): NAs introduced by coercion
## [1] "1  valores do vetor não são numéricos e foram excluídos"
## [1] 3
v1 <- LETTERS
amedia(v1)
## Warning in amedia(v1): NAs introduced by coercion
## [1] "O objeto não é um vetor ou não há valores numéricos"
## NULL

6.4.2 Exemplo II

Os loops por meio da expressão for(){} e a condicional if são muito úteis dentro de funções. Sua função pode, por exemplo, ser construida para que um argumento possa assumir diferentes valores e, a depender do valor, executar uma coisa diferente. Como exemplo, vamos criar uma função que contem o script do exemplo de if:

# CRIA uma funcao com os seguintes argumentos:
# vet = um vetor de valores
# busca.valor = um valor para busca em vet
# nrun = numero de vezes da iteracao
minhafuncao <- function(vet, busca.valor, nrun) {
  # cria um loop do número de vezes (note o argumento nrun abaixo)
  for (v in 1:nrun) {
    # pega um valor aleatorio
    # amostra o indice aleatoriamente
    idx <- sample(1:length(vet), 1)
    valor <- vet[idx]
    # se o valor amostrado for igual ao valor procurado para
    if (valor == busca.valor) {
      # se o valor selecionado aleatoriamente for 10, ou seja se a expressão valor==10 for TRUE execute:
      # imprima isso
      # print(paste("A primeira vez que o valor 10 foi selecionado aleatoriamente foi quando o objeto v assumiu o valor de",v))
      # interrompa (quebre) o loop
      break # note este argumento
    } else {
      # caso contrario, valor!=10, imprime o valor selecionado e continua o loop
      # print(paste("O valor selecionado foi ",valor,"no indice",v))
    }
  }
  # o valor do objeto v será o último valor assumido na execucao do for(){}, se tiver encontrado será menor que nrun, caso contrario será ==nrun
  # se encontrou retorna o indice do valor (que é o último valor assumido por idx)
  # caso o último valor seja == ao valor buscado, ou que o ultimo v é menor que o especificado em nrun, retorna o indice do valor no vetor vet
  if (v < nrun | valor == busca.valor) {
    print(paste("Encontrei o valor", busca.valor, "no indice, ", idx, "do vetor indicado"))
    return(idx)
  } else {
    # caso contrário returna NA
    print(paste("Não encontrei o valor", busca.valor, "no vetor indicado"))
    return(NA)
  }
}

Vamos utilizar a função recém-criada:

umvetor <- sample(10:100, 60, replace = T)
minhafuncao(vet = umvetor, busca.valor = 22, nrun = 1000)
## [1] "Não encontrei o valor 22 no vetor indicado"
## [1] NA
retornou.isso <- minhafuncao(vet = umvetor, busca.valor = 22, nrun = 1000)
## [1] "Não encontrei o valor 22 no vetor indicado"
# e usar de novo com outros valores
umvetor <- sample(200:300, 50, replace = T)
sort(table(umvetor), decreasing = T)[1:10]
255 210 219 228 260 261 264 269 201 202
3 2 2 2 2 2 2 2 1 1
minhafuncao(vet = umvetor, busca.valor = 250, nrun = 10000)
## [1] "Encontrei o valor 250 no indice,  36 do vetor indicado"
## [1] 36
retornou.isso <- minhafuncao(vet = umvetor, busca.valor = 250, nrun = 10000)
## [1] "Encontrei o valor 250 no indice,  36 do vetor indicado"

6.5 Para saber mais:

  1. Acesse vídeoaulas com conteúdo parcial deste capítulo clicando no tópicos abaixo:
  1. Auxílio do R - executem a expressão ?Control no R e vejam a explicação sobre condicionais.