Ferramentas do usuário

Ferramentas do site


biometria:backup:2007:r-tutor:07-programar

Uso da Linguagem R para Análise de Dados em Ecologia

7. Noções de Programação em Linguagem S

R: Um Ambiente Orientado a Objetos

Atributos

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
>   

Funções

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")
>   

Mundo dos Objetos

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
>       

Exercícios

<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>

Construindo Funções Simples

A Estrutura Básica de uma Função

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:

  • minha.funcao é o nome que a nova função receberá;
  • function é a expressão no R que cria uma nova função;
  • entre os parênteses “()“ são listados (separados por vírgula) os argumentos necessários a função;
  • entre as chaves ”{}“ são listados os comandos da função, sempre com um comando por linha.

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

Exercícios

<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:

  • Razão Variância-Média: s<latex> s^2 / \overline{x} </latex>; * Coeficiente de Green: <latex> \left[ (s^2 /\overline{x}) - 1\right] / \left[ \sum x_i - 1 \right] </latex>; * Índice de Morisita: <latex> n \left[ \sum x_i^2 - \sum x_i \right] / \left[ (\sum x_i)^2 - \sum x_i \right]</latex>. onde <latex> x_i </latex> são dados de contagem de uma espécie por parcela. Construa uma função para cada um desses índices, assumindo como argumento os valores de <latex> x_i</latex>. Aplique aos dados de caixetais, verificando a dispersão da árvores de caixeta em cada caixetal. </box> ==== Definindo Argumentos ==== Todos argumentos de uma função tem seu respectivo nome. Ao evocar a função podemos fazê-lo de duas formas: * utilizando o nome dos argumentos em qualquer ordem; * utilizando a ordem dos argumentos, mas omitindo os nomes. <code> > plot( col=“red”, pch=2, y=egr$ht, x=egr$dap ) > plot( egr$dap, egr$ht ) </code> Para qualquer argumento podemos definir um valor default apresentando esse valor junto com argumento na definição da função: <code> > myplot ← function(…, col=“red”) { plot(…, col=“red”) } > myplot( cax$dap, cax$h ) > myplot( ht ~ dap, data=egr ) </code> O exemplo acima também mostra a função do argumento ”. . .”. Esse argumento representa qualquer argumento adicional que desconhecemos, mas que desejamos que seja passado para as funções dentro da função que estamos construindo. === Exercícios === <box 100% left red | Exercícios: Gráfico de Whittaker > Faça uma função para construir o gráfico de diversidade de espécies de Whittaker: logaritmo da abundância contra a ordem (descrescente) da abundância das espécies. Construa essa função de forma que qualquer parâmetro gráfico possa ser alterado. </box> ===== Trabalhando com Funções mais Complexas ===== ==== Um Aspecto Prático ==== Construir funções na linha de comando é um trabalho muito pouco prático. Há duas alternativas mais práticas: - Usar a função “edit” para editar suas funções dentro do próprio R. Nesse caso você terá que utilizar o editor padrão do R. - Editar suas funções fora do R e trazê-las para dentro utilizando o comando “source”. Para saber qual é o editor padrão do R use o comando: <code> > getOption(“editor”) [1] “vi” > </code> Para alterar o editor padrâo use o comando: <code> > options( editor= “gedit” ) # Faz o editor “gedit” ser o editor padrão do R </code> No caso de editar sua função num editor externo ao R (p.ex., no arquivo '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>
biometria/backup/2007/r-tutor/07-programar.txt · Última modificação: 2022/11/24 14:21 por 127.0.0.1