\documentclass[a4paper, oneside, 10pt]{article} \usepackage[english]{babel} \usepackage[unicode]{hyperref} \usepackage[utf8x]{inputenc} \usepackage{graphicx} \graphicspath{{media/}} \usepackage{listings} \date{\today} \title{} \author{} \begin{document} \begin{itemize} \item \href{http://ecor.ib.usp.br/doku.php?id=02_tutoriais:tutorial8:start}{Tutorial} \item \href{http://ecor.ib.usp.br/doku.php?id=01_curso_atual:exercicios9}{ Exercícios} \item \href{http://ecor.ib.usp.br/doku.php?id=03_apostila:programar_ale}{ Apostila} \end{itemize} \section{\texorpdfstring{9. Noções de Programação}{9 Nooes de Programaao}} \label{sec:9_nooes_de_programaao} \subsection{\texorpdfstring{R: Um Ambiente Orientado a Objetos}{R Um Ambiente Orientado a Objetos}} \label{sec:r_um_ambiente_orientado_a_objetos} \subsubsection{\texorpdfstring{Atributos}{Atributos}} \label{sec: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 \textbf{objetos}. Veremos no decorrer do curso vários outros \textbf{objetos} do R. A importância do conceito de \textbf{objeto} num ambiente de trabalho de análise de dados é que os objetos possuem \textbf{atributos}, os quais podem variar em função do tipo de objeto. Vejamos um exemplo. \lstset{frame=single, language=rsplus} \begin{lstlisting} > 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á" > \end{lstlisting} O vetor \texttt{'zoo}' é um vetor de classe \texttt{'numeric}', de comprimento (\texttt{'length}') 4 e com nomes (\texttt{'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 \texttt{'names}' é opcional:\lstset{frame=single, language=rsplus} \begin{lstlisting} > b [1] 1 2 3 4 5 6 7 8 > class( b ) [1] "integer" > length( b ) [1] 8 > names( b ) NULL > \end{lstlisting} A função \texttt{'attributes}' nos mostra os atributos de um objeto, mas é de uso limitado no caso de vetores:\lstset{frame=single, language=rsplus} \begin{lstlisting} > 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 > \end{lstlisting} \subsubsection{\texorpdfstring{Funções}{Funoes}} \label{sec:funoes} As funções do R também são objetos, mas da classe \texttt{'function}':\lstset{frame=single, language=rsplus} \begin{lstlisting} > class( ls ) [1] "function" > class( log ) [1] "function" > class( sin ) [1] "function" > \end{lstlisting} No caso das funções, podemos associar a elas os \textbf{argumentos} que elas necessitam para serem executadas:\lstset{frame=single, language=rsplus} \begin{lstlisting} > args( ls ) function (name, pos = -1, envir = as.environment(pos), all.names = FALSE, pattern) NULL > args( log ) function (x, base = exp(1)) NULL > \end{lstlisting} Algumas funções matemáticas, no entanto, tem sempre apenas um argumento e são consideradas \textbf{funções primitivas}:\lstset{frame=single, language=rsplus} \begin{lstlisting} > args( sin ) NULL > sin .Primitive("sin") > > args( exp ) NULL > exp .Primitive("exp") > \end{lstlisting} \subsubsection{\texorpdfstring{Mundo dos Objetos}{Mundo dos Objetos}} \label{sec:mundo_dos_objetos} Um aspecto importante num ambiente orientado a objetos é que \textbf{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:\lstset{frame=single, language=rsplus} \begin{lstlisting} > 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 > \end{lstlisting} Quando o R nos mostra, como resultado de uma operação, valores como \texttt{'NULL}' e \texttt{'integer(0)}' ele está dizendo que o resultado é \textbf{vazio}, isto é, não há resultado: \lstset{frame=single, language=rsplus} \begin{lstlisting} > b [1] 1 2 3 4 5 6 7 8 > names( b ) NULL > b[ b > 10 ] integer(0) > \end{lstlisting} Veja que o valor \texttt{'NULL}' é um valor válidos que podem ser utilizados.\lstset{frame=single, language=rsplus} \begin{lstlisting} > 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 > \end{lstlisting} \paragraph{\texorpdfstring{Exercícios}{Exercicios}} \label{sec:exercicios} \emph{\textbf{Exercício 7.1:} Freqüência de Espécies } Considere o vetor com nome de espécies: \begin{quote} sp \end{quote} [1] ,,Myrcia sulfiflora" ,,Syagrus romanzoffianus" ,,Tabebuia cassinoides" [4] ,,Myrcia sulfiflora" \begin{quote} \end{quote} Para obter a freqüência das espécies podemos usar a função \texttt{'table}':\lstset{frame=single, language=rsplus} \begin{lstlisting} > table( sp ) sp Myrcia sulfiflora Syagrus romanzoffianus Tabebuia cassinoides 2 1 1 > \end{lstlisting} Qual a classe do objeto que a função \texttt{'table}' retorna? Quais são os seus attributos? \emph{\textbf{Exercício 7.2:} Classe da Classe } Qual a classe do objeto produzido pelo comando \texttt{'class( x )}'? \subsection{\texorpdfstring{Construindo Funções Simples}{Construindo Funoes Simples}} \label{sec:construindo_funoes_simples} \subsubsection{\texorpdfstring{A Estrutura Básica de uma Função}{A Estrutura Basica de uma Funao}} \label{sec:a_estrutura_basica_de_uma_funao} 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 é:\lstset{frame=single, language=rsplus} \begin{lstlisting} > minha.funcao <- function( argumento1, argumento2, argumento3, . . .) { comando 1 comando 2 comando 3 . . . comando n return("resultado") } \end{lstlisting} Os elementos dessa expressão são: \begin{itemize} \item \textbf{minha.funcao} é o nome que a nova função receberá; \item \textbf{function} é a expressão no R que cria uma nova função; \item \textbf{entre as chaves ,,\{\},,} são listados os comandos da função, sempre com um comando por linha; \item \textbf{entre os parênteses "(),,} são listados (separados por vírgula) os argumentos necessários a função; \item \textbf{comando return(,,resultado") } retorna os resultados, caso falte, será apresentado o resultado do último comando (comando n). \end{itemize} Vejamos alguns exemplos simples:\lstset{frame=single, language=rsplus} \begin{lstlisting} ##criar um vetor de dados com 20 valores aleatórios de uma distribuição Poisson dados.dens<-rpois(20,lambda=6) ##funcão para calcular média media.curso <-function(x,rmNA=TRUE) { soma=sum(x) nobs=length(x) media=soma/nobs return(media) } ##Vamos agora preparar uma função mais elaborada, considerando a ##presença e excluíndo NA por padrão, e lançando mensagem na tela ##sobre o número de NAs removidos. Note que é uma função com dois argumentos ##que permite ao usuário tomar a decisão de remover ou não NAs e avisando, ##diferente da função mean() media.curso <-function(x,rmNA=TRUE) { if(rmNA==TRUE) { dados=(na.omit(x)) dif=length(x)-length(dados) cat("\t", dif," valores NA excluídos\n") } else { dados=x } soma=sum(dados) nobs=length(dados) media=soma/(nobs) return(media) } ###calcular a média do objeto dados media.curso(dados.dens) ########################################## ###função para calcular variância var.curso<-function(x) { media=media.curso(x) dados=na.omit(x) disvquad=(dados-media)^2 variancia=sum(disvquad)/(length(dados)-1) return(variancia) } ###Calcular a variância de dados var.curso(dados.dens) ###Tomando dados.dens como a contagem de uma espécie em uma amostra de 20 parcelas de 20x20m, ###podemos verificar o padrão de dispersão dessa espécie, utilizando o Índice de Dispersão (razão variância / média) ID.curso<-function(x) { id=var.curso(x)/media.curso(x) return(id) } ##Calcular o coeficiente de dispersão ID.curso(dados.dens) ## quando o valor é próximo a 1 a distribuição é considerada aleatória. ## podemos fazer um teste de significância pela aproximação com o valor Qui-Quadrado para verificar a significância dos dados test.ID <- function(x) { dados=na.omit(x) med=media.curso(x) dev.quad=(dados-med)^2 qui=sum(dev.quad)/med critico.qui<-qchisq(c(0.025,0.975),df=(length(dados)-1)) if(critico.qui[1]<=qui & critico.qui[2]>=qui) { cat("\t distribuição aleatória para alfa=0.05\n")} else{} if(qui < critico.qui[1]) { cat("\t","distribuição agregada, p<0.025 \n")} else{} if(qui>critico.qui[2]) { cat("\t","distribuição regular, p>0.975 \n")} resulta=c(qui,critico.qui) names(resulta)<-c("qui-quadrado", "critico 0.025", "critico 0.975") return(resulta) } ############ \end{lstlisting} \paragraph{\texorpdfstring{Exercícios}{Exercicios}} \label{sec:exercicios2} \emph{\textbf{Exercício 7.3:} QUE FRIO! } Construa uma função que calcula automaticamente o valor de graus Celsius, sabendo-se a temperatura em Fahrenheit. C° = 5/9 * (F°(temperatura dada) - 32) \emph{\textbf{Exercício 7.4:} Somatório do Primeiros Números Naturais } Construa uma função que calcula o somatório dos primeiros \emph{n} números naturais. Por exemplo se \emph{n=4} a função deve retornar o valor: \emph{1+2+3+4}. \emph{\textbf{Exercício 7.5:} Í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: \begin{itemize} \item \textbf{Razão Variância-Média}: ID = variância / média; \end{itemize} \begin{itemize} \item \textbf{Coeficiente de Green}: IG = (ID-1)/(n-1); \end{itemize} \begin{itemize} \item \textbf{Índice de Morisita}: \end{itemize} \includegraphics[keepaspectratio=true,width=0.8\textwidth]{03_apostila/indice_morisita} onde: n = tamanho da amostra; xi= número de indivíduos na i -ésima unidade amostral Construa uma função para cada um desses índices, assumindo como argumento os valores de xi. Aplique aos dados de caixetais, verificando a dispersão da árvores de caixeta em cada caixetal. \subsubsection{\texorpdfstring{Definindo Argumentos}{Definindo Argumentos}} \label{sec:definindo_argumentos} Todos argumentos de uma função tem seu respectivo nome. Ao evocar a função podemos fazê-lo de duas formas: \begin{itemize} \item utilizando o \textbf{nome} dos argumentos \textbf{em qualquer ordem}; \item utilizando a \textbf{ordem} dos argumentos, mas \textbf{omitindo} os nomes. \end{itemize} \lstset{frame=single, language=rsplus} \begin{lstlisting} > plot( col="red", pch=2, y=egr$ht, x=egr$dap ) > plot( egr$dap, egr$ht ) \end{lstlisting} Para qualquer argumento podemos definir um \textbf{valor default} apresentando esse valor junto com argumento na definição da função:\lstset{frame=single, language=rsplus} \begin{lstlisting} > myplot <- function(..., col="red") { plot(..., col="red") } > myplot( cax$dap, cax$h ) > myplot( ht ~ dap, data=egr ) \end{lstlisting} O exemplo acima também mostra a função do argumento \textbf{". . ."}. Esse argumento representa \textbf{qualquer argumento adicional} que desconhecemos, mas que desejamos que seja passado para as funções dentro da função que estamos construindo. \paragraph{\texorpdfstring{Exercícios}{Exercicios}} \label{sec:exercicios3} \emph{\textbf{Exercício 7.6:} 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. \subsection{\texorpdfstring{Trabalhando com Funções mais Complexas}{Trabalhando com Funoes mais Complexas}} \label{sec:trabalhando_com_funoes_mais_complexas} \subsubsection{\texorpdfstring{Um Aspecto Prático}{Um Aspecto Pratico}} \label{sec:um_aspecto_pratico} Para saber qual é o editor padrão do R use o comando:\lstset{frame=single, language=rsplus} \begin{lstlisting} > getOption("editor") [1] "vi" > \end{lstlisting} Para alterar o editor padrâo use o comando:\lstset{frame=single, language=rsplus} \begin{lstlisting} > options( editor= "gedit" ) # Faz o editor "gedit" ser o editor padrão do R \end{lstlisting} No caso de editar sua função num editor externo ao R (p.ex., no arquivo \texttt{'minhas-funcoes.R}'), você traz o código para dentro do R utilizando o comando \textbf{,,source"}:\lstset{frame=single, language=rsplus} \begin{lstlisting} > source( "minhas-funcoes.R" ) \end{lstlisting} É importante que o arquivo editado externamente (\texttt{'minhas-funcoes.R}') seja um arquivo \textbf{ASCII} sem qualquer símbolo especial. \paragraph{\texorpdfstring{Exercícios}{Exercicios}} \label{sec:exercicios4} \emph{\textbf{Exercícios:} Editando Funções Externamente } Experimente definir um editor com o qual você consiga trabalhar (\texttt{'gedit}'?) e refaça os exercícios anteriores salvando todos os códigos num arquivo externo. \emph{\textbf{Exercícios:} Índices de Diversidade de Espécies } Construa funções para computar os seguintes índices de diversidade de espécies: \begin{itemize} \item Índice de Shannon: \texttt{H = - ∑ (p\emph{i} * ln( p\emph{i} ))} \end{itemize} \begin{itemize} \item Índice de Simpson: \texttt{D = ∑(p\emph{i}\textasciicircum{}2)} \end{itemize} onde p\emph{i} é a proporção da espécie \emph{i} Considere que o argumento de sua função será uma matriz com a abundância das espécies sendo as parcelas amostradas nas colunas. Considere a possibilidade de haver NA nessa matrix e a remoção dele. \subsubsection{\texorpdfstring{Realizando Loops}{Realizando Loops}} \label{sec:realizando_loops} Em linguagem de programação um \textbf{loop} é quando você força um programa a executar uma série de comandos repedidas vêzes. A estrutura de loop no R é:\lstset{frame=single, language=rsplus} \begin{lstlisting} for( "variável" in "vetor de valores") { comando 1 comando 2 comando 3 . . . comando n } \end{lstlisting} A palavra \textbf{for} é o chamado do loop. Dentro dos parênteses se define uma variável seguida da palavra \textbf{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: \emph{Convergência da distribuição t de Student para distribuição Normal Padronizada}:\lstset{frame=single, language=rsplus} \begin{lstlisting} > # > # 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") + } > \end{lstlisting} No exemplo acima temos: \begin{itemize} \item \texttt{'gl}' é a variável definida para o loop; \item \texttt{'1:200}' é o vetor de valores que a variável assumirá, logo, o loop será repetido 200 vêzes. \end{itemize} \paragraph{\texorpdfstring{Exercícios}{Exercicios}} \label{sec:exercicios5} \emph{\textbf{Exercícios:} Loop para Demonstrar o TCL } Construa uma função para demonstrar o Teorema Central do Limite. \subsubsection{\texorpdfstring{Solução Vetorial x Loop}{Soluao Vetorial x Loop}} \label{sec:soluao_vetorial_x_loop} Sendo um \textbf{ambiente vetorial}, os \emph{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 \textbf{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 memória RAM do computador. Considere o problema o seguinte problema: temos a localização espacial de plantas num plano cartesiano com coordenadas \textbf{(x,y)}. Por exemplo:\lstset{frame=single, language=rsplus} \begin{lstlisting} > x = runif(100) > y = runif(100) > plot(x,y) \end{lstlisting} O objetivo é obter as \textbf{distâncias} entre as plantas duas-a-duas. Primeiro consideremos uma solução através de loop:\lstset{frame=single, language=rsplus} \begin{lstlisting} 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 } \end{lstlisting} Consideremos agora uma solução vetorial:\lstset{frame=single, language=rsplus} \begin{lstlisting} 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 } \end{lstlisting} Qual dessas soluções é mais eficiente em termos do uso do tempo?\lstset{frame=single, language=rsplus} \begin{lstlisting} > 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 \end{lstlisting} \textbf{Não tente rodar o exemplo acima com 1000 ou mais observações}, pois o tempo fica \textbf{realmente longo} para versão em loop. \textbf{CONCLUSÃO:} use apenas \textbf{pequenos loops} no R!!! \paragraph{\texorpdfstring{Exercícios}{Exercicios}} \label{sec:exercicios6} \emph{\textbf{Exercícios:} Tabela de Fitossociologia } Construa uma função que gera uma tabela de fitossociologia. Utilize os dados de caixeta (\href{http://ecor.ib.usp.br/doku.php?id=dados:dados-caixeta}{dados:dados-caixeta}) como teste. \subsubsection{\texorpdfstring{APÊNDICE: Tabela de Operadores do R}{APENDICE Tabela de Operadores do R}} \label{sec:apendice_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:\lstset{frame=single, language=rsplus} \begin{lstlisting} ================================================================= 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 ================================================================= \end{lstlisting} \end{document}