~~NOTOC~~
1 ######################################################
2 ########### 5. NOÇÕES DE PROGRAMAÇÃO
3 ########### 5.3. Controle de Fluxo
4 ######################################################
5 # 5.3.1. "For Loop"
6
7 converg.t2z = function( gl.max = 200)
8 {
9 #
10 # Convergência da distribuição t de Student
11 # para distribuição Gaussiana Padronizada
12 #
13 curve(dnorm(x), from=-4, to=4, col="red", lwd=6)
14 for(gl in 1:gl.max)
15 {
16 curve(dt(x, gl), -4, 4, add=TRUE, col="green")
17 for(i in 1:100000) i
18 }
19 }
20
21 converg.t2z()
22
No exemplo acima temos a função **''converg.t2z''** com os seguintes elementos:
* **''gl''** é a variável definida para o "loop";
* **''1:gl.max''** é o vetor de valores que a variável assumirá, logo, o "loop" será repetido **gl.max** vêzes. O valor do argumento **''gl.max''** é definido por //__default__// como sendo 200.
\\
===== 5.3.2. Solução Vetorial x Loop =====
-------------------------------------
Sendo um //__ambiente vetorial__// os "loops" não são uma opção muito eficiente para computação dentro do R. Em geral, o R é mais eficiente se encontrarmos uma //__solução vetorial__// para problemas de computação que aparentemente exigem um loop. A solução vetorial, entretanto, costuma ser mais exigente em termos do tamanho de da memória RAM do computador.
Considere o problema o seguinte problema: temos a localização espacial de plantas num plano cartesiano com coordenadas **''(x,y)''**. Por exemplo:
23 # 5.3.2. Solução Vetorial x Loop
24
25 x = runif(100)
26 y = runif(100)
27 plot(x,y)
28
O objetivo é obter as //__distâncias__// entre as plantas duas-a-duas. Primeiro consideremos uma solução através de "loop":
29 inter.edist = function(x, y)
30 {
31 n = length(x)
32 dist <- c()
33 for(i in 1:(n-1))
34 {
35 for(j in (i+1):n)
36 {
37 dist <- c(dist, sqrt( (x[i] - x[j])^2 + (y[i] - y[j])^2 ))
38 }
39 }
40 dist
41 }
42
Consideremos agora uma solução vetorial:
43 inter.edist.v = function(x, y)
44 {
45 xd <- outer( x, x, "-" )
46 yd <- outer( y, y, "-" )
47 z <- sqrt( xd^2 + yd^2 )
48 dist <- z[ row(z) > col(z) ]
49 dist
50 }
51
Qual dessas soluções é mais eficiente em termos do uso do tempo?
52 x = runif(400)
53 y = runif(400)
54 plot(x,y)
55
56 system.time( inter.edist(x,y) )
57 system.time( inter.edist.v(x,y) )
58
59 # 5.3.3. Controle de Fluxo: "If"
60
61 example.if = function(x)
62 {
63 y = 2*x
64 if( !is.null(names(y)) )
65 {
66 y.nm = names(y)
67 print(y.nm)
68 }
69 y
70 }
71
//__Observação__//: a função **''is.null''** retorna o valor **''TRUE''** se o seu argumento for nulo (**''NULL''**).
Um exemplo de aplicação da função **''example.if''**:
72 x = 1:3
73 x2 = x
74 names(x2) = c("a","b","c")
75
76 example.if(x)
77 example.if(x2)
78
\\
===== 5.3.4. Controle de Fluxo: "If Else" =====
-------------------------------------
O controle **''if else''** definir a seguinte situação:
* a condição lógica é //__verdadeira__//: executa-se o conjunto de instruções //__A__// (instruções 2 e 3, na figura abaixo);
* a condição lógica é //__falsa__//: executa-se o conjunto de instruções //__B__// (instruções 4 e 5, na figura abaixo).
79 # 5.3.4. Controle de Fluxo: "If Else"
80
81 example.ifelse = function(x)
82 {
83 y = 2*x
84 if( !is.null(names(y)) )
85 {
86 print(names(y))
87 }
88 else
89 {
90 print(y)
91 }
92 print("Fim do controle IF-ELSE")
93 }
94
Aplicando a função:
95 x = 1:3
96 x2 = x
97 names(x2) = c("a","b","c")
98
99 example.ifelse(x)
100 example.ifelse(x2)
101
\\
===== 5.3.5. Controle de Fluxo: "Stop" =====
-------------------------------------
A função **''stop''** ela aborta a execução das instruções na linha em que ela for colocada, //__executando uma ação de erro__//. Vejamos um exemplo:
102 # 5.3.5. Controle de Fluxo: "Stop"
103
104 example.stop = function(x,y)
105 {
106 if( length(x) != length(y) )
107 stop("Os vetores 'x' e 'y' devem ter o mesmo comprimento")
108 out = cbind(x,y)
109 out
110 }
111
Uma exemplo de aplicação:
112 x1 = 1:5
113 x2 = 6:10
114 x3 = 11:20
115
116 example.stop(x1,x2)
117 example.stop(x1,x3)
118
\\
----------------
\\