Uso da Linguagem R para Análise de Dados em Ecologia
Até esse ponto do curso, foi visto que existem no R funções, variáveis e vetores. Todos esses ítens são chamados genericamente de objetos.
Veremos no decorrer do curso vários outros objetos do R. A importância do conceito de objeto num ambiente de trabalho de análise de dados é que os objetos possuem atributos, os quais podem variar em função do tipo de objeto.
Vejamos um exemplo.
> zoo onça anta tatu guará 4 10 2 45 > class( zoo ) [1] "numeric" > length( zoo ) [1] 4 > names( zoo ) [1] "onça" "anta" "tatu" "guará" >
O vetor 'zoo
' é um vetor de classe 'numeric
', de comprimento ('length
') 4 e com nomes ('names
'): onça, anta, tatu e guará. Classe, comprimento e nomes são os atributos típicos de vetores.
Qualquer vetor sempre terá uma classe e um comprimento, mas o atributo 'names
' é opcional:
> b [1] 1 2 3 4 5 6 7 8 > class( b ) [1] "integer" > length( b ) [1] 8 > names( b ) NULL >
A função 'attributes
' nos mostra os atributos de um objeto, mas é de uso limitado no caso de vetores:
> zoo onça anta tatu guará 4 10 2 45 > attributes( zoo ) $names [1] "onça" "anta" "tatu" "guará" > b [1] 1 2 3 4 5 6 7 8 > attributes( b ) NULL >
As funções do R também são objetos, mas da classe 'function
':
> class( ls ) [1] "function" > class( log ) [1] "function" > class( sin ) [1] "function" >
No caso das funções, podemos associar a elas os argumentos que elas necessitam para serem executadas:
> args( ls ) function (name, pos = -1, envir = as.environment(pos), all.names = FALSE, pattern) NULL > args( log ) function (x, base = exp(1)) NULL >
Algumas funções matemáticas, no entanto, tem sempre apenas um argumento e são consideradas funções primitivas:
> args( sin ) NULL > sin .Primitive("sin") > > args( exp ) NULL > exp .Primitive("exp") >
Um aspecto importante num ambiente orientado a objetos é que tudo o que o ambiente trabalha são objetos e o ambiente não pode trabalhar com nada que não seja um objeto conhecido. Inclui nessa categoria tudo aquilo que o R apresenta na tela, por isso toda saída do R pode ser guardada num objeto:
> length( zoo ) [1] 4 > zoo.comp = length( zoo ) > zoo.comp [1] 4 > class( zoo ) [1] "numeric" > zoo.class = class( zoo ) > zoo.class [1] "numeric" > class( zoo.class ) [1] "character" > names( zoo ) [1] "onça" "anta" "tatu" "guará" > class( names( zoo ) ) [1] "character" > length( names( zoo ) ) [1] 4 >
Quando o R nos mostra, como resultado de uma operação, valores como 'NULL
' e 'integer(0)
' ele está dizendo que o resultado é vazio, isto é, não há resultado:
> b [1] 1 2 3 4 5 6 7 8 > names( b ) NULL > b[ b > 10 ] integer(0) >
Veja que o valor 'NULL
' é um valor válidos que podem ser utilizados.
> zoo2 = zoo > zoo2 onça anta tatu guará 4 10 2 45 > names( zoo2 ) [1] "onça" "anta" "tatu" "guará" > names( zoo2 ) = NULL > zoo2 [1] 4 10 2 45 > names( zoo2 ) NULL >
<box 100% left red | Exercícios: Freqüência de Espécies > Considere o vetor com nome de espécies:
> sp [1] "Myrcia sulfiflora" "Syagrus romanzoffianus" "Tabebuia cassinoides" [4] "Myrcia sulfiflora" > Para obter a freqüência das espécies podemos usar a função '''table''': <code> > table( sp ) sp Myrcia sulfiflora Syagrus romanzoffianus Tabebuia cassinoides 2 1 1 >
Qual a classe do objeto que a função 'table
' retorna? Quais são os seus attributos?
</box>
<box 100% left red | Exercícios: Classe da Classe >
Qual a classe do objeto produzido pelo comando 'class( x )
'?
</box>
Toda manipulação de dados e análises gráficas e estatísticas no R são realizadas através de funções. Entretanto, você não precisa ser um programador experimentado para construir algumas funções simples para facilitar a atividade de manipulação de dados.
A estrutura básica de uma função é:
minha.funcao <- function( argumento1, argumento2, argumento3, . . .) { comando 1 comando 2 comando 3 . . . comando n }
Os elementos dessa expressão são:
Vejamos um exemplo simpes:
> sincos <- function(x) + { + sin(x) * cos(x) + } > sincos(10) [1] 0.4564726 > sin(10) * cos(10) [1] 0.4564726 > > sincos(pi) [1] -1.224647e-16 > sin(pi) * cos(pi) [1] -1.224647e-16
<box 100% left red | Exercícios: Logaritmo na Base 2 > Construa uma função que calcula automaticamente o logaritmo na base 2. </box>
<box 100% left red | Exercícios: Somatório do Primeiros Números Naturais > Construa uma função que calcula o somatório dos primeiros n números naturais.
Por exemplo se n=4 a função deve retornar o valor: 1+2+3+4. </box>
<box 100% left red | Exercícios: Índices de Dispersão I > Existe uma série de índices de dispersão baseados em dados de contagem para verificar o padrão espacial de uma espécie.
Alguns deles são:
'minhas-funcoes.R
'), você traz o código para dentro do R utilizando o comando “source”:
<code>
> source( “minhas-funcoes.R” )
</code>
É importante que o arquivo editado externamente ('minhas-funcoes.R
') seja um arquivo ASCII sem qualquer símbolo especial.
=== Exercícios ===
<box 100% left red | Exercícios: Editando Funções Externamente >
Experimente definir um editor com o qual você consiga trabalhar ('gedit
'?) e refaça os exercícios anteriores salvando todos os códigos num arquivo externo.
</box>
<box 100% left red | Exercícios: Índices de Diversidade de Espécies >
Construa funções para computar os seguintes índices de diversidade de espécies:
* Índice de Shannon: <latex> H = - \sum_{i=1}^S p_i \ln( p_i ) </latex>
* Índice de Simpson: <latex> D = \sum_{i=1}^S (p_i)^2 </latex>
onde <latex> p_i </latex> é a proporção da espécie i.
Considere que o argumento de sua função será um vetor com o nome das espécies para cada planta.
</box>
==== Realizando “Loops” ====
Em linguagem de programação um loop é quando você força um programa a executar uma série de comandos repedidas vêzes.
A estrutura de loop no R é:
<code>
for( “variável” in “vetor de valores”)
{
comando 1
comando 2
comando 3
. . .
comando n
}
</code>
A palavra for é o chamado do loop. Dentro dos parênteses se define uma variável seguida da palavra in e um vetor de valores que a variável deverá assumir. Dentro das chaves se lista os comandos que devem ser repeditos a cada passo do loop.
Vejamos um exemplo: Convergência da distribuição t de Student para distribuição Normal Padronizada:
<code>
> #
> # Convergência da distribuição t de Student para distribuição Normal Padronizada
> #
> curve(dnorm(x), from=-4, to=4, col=“red”, lwd=6)
> for(gl in 1:200)
+ {
+ curve(dt(x, gl), -4, 4, add=TRUE, col=“green”)
+ }
>
</code>
No exemplo acima temos:
* 'gl
' é a variável definida para o loop;
* '1:200
' é o vetor de valores que a variável assumirá, logo, o loop será repetido 200 vêzes.
=== Exercícios ===
<box 100% left red | Exercícios: Loop para Demonstrar o TCL >
Construa uma função para demonstrar o Teorema Central do Limite.
</box>
==== Solução Vetoria 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:
<code>
> x = runif(100)
> y = runif(100)
> plot(x,y)
</code>
O objetivo é obter as distâncias entre as plantas duas-a-duas. Primeiro consideremos uma solução através de loop:
<code>
inter.edist = function(x, y)
{
n = length(x)
dist ← c()
for(i in 1:(n-1))
{
for(j in (i+1):n)
{
dist ← c(dist, sqrt( (x[i] - x[j])^2 + (y[i] - y[j])^2 ))
}
}
dist
}
</code>
Consideremos agora uma solução vetorial:
<code>
inter.edist.v = function(x, y)
{
xd ← outer( x, x, “-” )
yd ← outer( y, y, “-” )
z ← sqrt( xd^2 + yd^2 )
dist ← z[ row(z) > col(z) ]
dist
}
</code>
Qual dessas soluções é mais eficiente em termos do uso do tempo?
<code>
> x = runif(100)
> y = runif(100)
>
> system.time( inter.edist( x, y ) )
[1] 0.140 0.008 0.149 0.000 0.000
>
> system.time( inter.edist.v( x, y ) )
[1] 0.008 0.000 0.009 0.000 0.000
</code>
Não tente rodar o exemplo acima com 1000 ou mais observações, pois o tempo fica realmente longo para versão em loop.
CONCLUSÃO: use apenas pequenos loops no R!!!
=== Exercícios ===
<box 100% left red | Exercícios: Tabela de Fitossociologia >
Construa uma função que gera uma tabela de fitossociologia. Utilize os dados de caixeta (dados-caixeta) como teste.
</box>
==== APÊNDICE: Tabela de Operadores do R ====
Outro aspecto formal importante da linguagem R é a ordem de prioridade de seus operadores. Além das regras de precedência usuais para as operações matemáticas, é essencial conhecer a prioridade dos outros operadores:
<box 80% red>
<code>
=================================================================
OPERADOR DESCRIÇÃO PRIORIDADE
=================================================================
$ seleção de componentes ALTA
[ [[ indexação |
^ potência |
- menos unitário |
: operador de seqüência |
%nome% operadores especiais |
* / multiplicação, divisão |
< > ⇐ >= == != comparação |
! não |
& && | || e, ou |
~ fórmula estatística \/
«- ← → = atribuição Baixa
=================================================================
</code>
</box>