Torgo ProgrammingIntro

Você também pode gostar

Você está na página 1de 99

Faculdade de Economia

Universidade do Porto

Introduo ` Programao em R ca a ca

Lu Torgo s ltorgo@liacc.up.pt Grupo de Matemtica e Informtica a a

Outubro de 2006

L. Torgo, 2006. A licence is granted for personal study and classroom use. Redistri-

bution in any other form is prohibited.

L. Torgo, 2006. E concedida licena de utilizao deste documento para uso pessoal c ca

e para ensino. A re-distribuiao em qualquer outro tipo de formato proibida. c e

Conte do u
1 Introduo ao Ambiente ca 1.1 Instalao do R . . . . ca 1.2 Comear a usar o R . c 1.3 Ajuda sobre o R . . . 1.4 Packages do R . . . . R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 7 9 9 11 11 12 14 15 18 20 22 26 27 29 31 31 36 45 45 46 46 48 50 52 52 53 54 56 56 58 60 63 63 63 64 65 65 67 70 71 73 74 78 81 83 84

2 Fundamentos da Linguagem R 2.1 Os objectos do R . . . . . . . 2.2 Vectores . . . . . . . . . . . . 2.3 Operaes com Vectores . . . co 2.4 Factores . . . . . . . . . . . . 2.5 Sequncias . . . . . . . . . . . e 2.6 Indexao . . . . . . . . . . . ca 2.7 Matrizes . . . . . . . . . . . . 2.8 Arrays . . . . . . . . . . . . . 2.9 Listas . . . . . . . . . . . . . 2.10 Data Frames . . . . . . . . . 2.11 Sries Temporais . . . . . . . e 2.11.1 Sries Regulares . . . e 2.11.2 Sries Irregulares . . . e

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

3 Programao em R ca 3.1 Interaco com o Utilizador . . . . . . . ca 3.2 Estruturas de Controlo da Linguagem R 3.2.1 Instrues Condicionais . . . . . co 3.2.2 Instrues Iterativas . . . . . . . co 3.2.3 Evitando ciclos . . . . . . . . . . 3.3 Funes . . . . . . . . . . . . . . . . . . co 3.3.1 Criar funes . . . . . . . . . . . co 3.3.2 Ambientes e scope de variveis a 3.3.3 Argumentos de funes . . . . . co 3.3.4 Lazy evaluation . . . . . . . . . . 3.3.5 Algumas funes uteis . . . . . . co 3.4 Objectos, Classes e Mtodos . . . . . . . e 3.5 Depurao de Programas em R . . . . . ca

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

4 Manipulao de Dados ca 4.1 Carregar dados para o R . . . . . . . . . . . . . . . 4.1.1 De cheiros de texto . . . . . . . . . . . . . 4.1.2 Da Internet . . . . . . . . . . . . . . . . . . 4.1.3 Do Excel . . . . . . . . . . . . . . . . . . . 4.1.4 De bases de dados . . . . . . . . . . . . . . 4.2 Sumarizao de dados . . . . . . . . . . . . . . . . ca 4.3 Frmulas . . . . . . . . . . . . . . . . . . . . . . . o 4.4 Visualizao de dados . . . . . . . . . . . . . . . . ca 4.4.1 Grcos Univariados . . . . . . . . . . . . . a 4.4.2 Grcos de 3 Variveis . . . . . . . . . . . . a a 4.4.3 Grcos Multivariados . . . . . . . . . . . . a 4.4.4 Grcos Condicionados . . . . . . . . . . . a 4.4.5 Interaco com Grcos . . . . . . . . . . . ca a 4.4.6 Adicionar Informao a Grcos Existentes ca a

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

4.4.7 4.4.8 Referncias e Indice

Parmetros de Grcos . . . . . . . . . . . . . . . . . . . . . . . . a a Dividir a Janela de Grcos em Vrias Areas . . . . . . . . . . . . a a

90 91 95 97

Prefcio a
Este documento tem como objectivo principal fornecer uma introduo ` programao ca a ca usando a linguagem R. A escolha desta linguagem como ve culo para aprender a programar prende-se com os objectivos do curso em que esta disciplina se insere. Uma vez que este curso tem a anlise de dados e o data mining como um dos assuntos centrais, a o R sendo tambm um ambiente de anlise exploratria de dados, permite uma melhor e a o articulao com outras disciplinas. ca A escolha do R tem ainda outros motivos relacionados com o facto de este ser um software gratuito e de cdigo aberto. Estas caracter o sticas, em conjunto com as suas reconhecidas qualidades, fazem dele uma ferramenta quase ideal para aprender a programar dentro dum contexto de anlise de dados e sistemas de apoio ` deciso. Ao usarem a a a uma ferramenta deste gnero como plataforma de implementao dos conceitos aprene ca didos, os alunos podero facilmente, pelo seu carcter gratuito, levar o que aprenderam a a para o cenrio prossional em que se enquadram ou venham a enquadrar. Alm disso, a e as suas caracter sticas de cdigo aberto iro facilitar a eventual necessidade de adaptar o a algum dos muitos mtodos dispon e veis no R, para assim melhor os adequarem aos seus interesses/objectivos.

Introduo ao Ambiente R ca
O que o R? e

O R (R Development Core Team, 2006) ao mesmo tempo uma linguagem de programae ca o e um ambiente para computao estat ca stica e grcos. Trata-se de uma linguagem de a programao especializada em computao com dados. Uma das suas principais caracteca ca r sticas o seu carcter gratuito e a sua disponibilidade para uma gama bastante variada e a de sistemas operativos. Neste documento iremos concentrar a nossa ateno na verso ca a Windows, mas basicamente tudo o que aqui descrito tambm se aplica `s outras verses, e e a o dadas as muito reduzidas diferenas entre as verses para as diversas plataformas. c o Apesar do seu carcter gratuito o R uma ferramenta bastante poderosa com boas a e capacidades ao n vel da programao e um conjunto bastante vasto (e em constante ca crescimento) de packages que acrescentam bastantes potencialidades ` j poderosa verso a a a base do R. O R uma variante da linguagem S com a qual John Chambers (Chambers, 1998) e ganhou o prestigiado prmio de software da organizao ACM. e ca

1.1

Instalao do R ca

Embora o R esteja instalado no sistema informtico da FEP, dado o seu carcter graa a tuito, os alunos podero instalar este software nos seus computadores em casa. Para isso a necessitaro simplesmente de ligar o computador ` Internet e seguir os passos que desa a crevemos em seguida. Caso no pretenda realizar a instalao do R no seu computador, a ca poder avanar para a prxima seco. a c o ca Para instalar o R os alunos devero comear por ligar o seu computador ` Internet. a c a Aps esta ligao dever ser feito o download do R a partir do site desta aplicao, o ca a ca http://www.r-project.org. Neste site dever ser seguido o link com o nome CRAN a no menu dispon ` esquerda. Depois de escolher um dos muitos locais espalhados pelo vel a mundo para fazer o download, dever seguir o link Windows (95 and later) dispon a vel na seco Precompiled Binary Distributions. No cran seguinte, deve entrar na pasta ca e base e fazer o download do cheiro R-2.3.1-win32.exe1 . Uma vez efectuado o download do cheiro mencionado acima, dever proceder-se ` a a instalao do R , bastando para isso executar o cheiro (carregando duas vezes em cima ca dele no Explorer). De notar que em verses mais recentes do Windows esta instalao o ca poder ter de ser feita pelo utilizador Administrador, por questes de permisses. a o o

Download do R

Instalao do R ca

1.2

Comear a usar o R c
Iniciar o R

Para se executar o R basta usar ou o cone que normalmente est dispon no desktop a vel do Windows, ou ento usar o respectivo item no menu Start2 . a A execuo do R faz aparecer a janela desta aplicao de que se pode ver um exemplo ca ca na Figura 1. ` A parte os menus que iremos explorar mais tarde, esta janela apresenta o prompt do R (> ), com o cursor ` sua frente. E aqui que vamos introduzir os comandos que a pretendemos que o R execute. Podemos comear por ver um pequeno exemplo do tipo de c interaco que vamos ter com o R, escrevendo o seguinte comando no prompt e carregando ca em seguida na tecla Enter (esta a forma de mandar o R executar o comando que e acabamos de escrever), > R.version platform i386-pc-mingw32 arch i386 os mingw32 system i386, mingw32 status
1 O nome do cheiro poder variar em verses posteriores do R. Na altura da escrita deste texto a a o verso do R dispon a vel era a 2.3.1 e da o nome do cheiro. 2 Na FEP o R est dispon a vel seguindo o percurso de menus: Start->Programs->Aplications->R.

O prompt do R

Executar comandos

INTRODUCAO AO AMBIENTE R

Figura 1: O ambiente R. major 2 minor 3.1 year 2006 month 06 day 01 svn rev 38247 language R version.string Version 2.3.1 (2006-06-01) O comando R.version ao ser executado fez aparecer uma srie de informao sobre e ca a verso do R bem como sobre o computador onde o R est a ser executado. a a Para terminar a execuo do R basta executar o seguinte comando, ca > q()
Continuar o trabalho mais tarde

Terminar o R

Ao executar este comando ir aparecer uma caixa de dilogo como a apresentada na a a Figura 2. Se respondermos Yes a esta pergunta o R vai guardar a informao contida na ca memria do computador num cheiro, de modo a que da prxima vez que executarmos o o o R no local onde esse cheiro guardado, ele vai permitir-nos continuar o nosso trabalho e exactamente de onde o estamos a abandonar ao executar o comando q(). A informao ca guardada consiste basicamente na histria de comandos que executamos nesta sesso que o a agora terminamos, bem como os objectos que criamos na nossa sesso. O resultado ser a a que o R vai criar 2 cheiros: um chamado .Rhistory contendo a lista dos comandos que executamos, e outro chamado .RData contendo os objectos criados na sesso. Gravar a a sesso s ter interesse se de facto pretendermos continuar o que estvamos a fazer mais a o a a tarde. Na maior parte das vezes vamos escolher a opo No que ir abandonar o R sem ca a guardar o estado em que estvamos. Os cheiros com o estado da sesso so sempre a a a gravados no directrio actual onde o R est a funcionar. Para saber o directrio actual o a o do R basta fazer no prompt, > getwd()

Alterar o directrio o actual

Em resposta a este comando o R ir apresentar no cran o directrio actual. Para o a e o alterar poder-se- ou usar a opo Change dir... do menu File, ou ento usar a funo a ca a ca setwd() conforme ilustrado no exemplo seguinte, > setwd('U:\\My Documents\\AulasR') Note a utilizao de dois caracteres \\, em vez do unico caracter como costume em ca e ambientes Windows3 .
3 Acrescente-se a t tulo de curiosidade que poder ser usado em vez destes dois caracteres um unico a caracter /.

1.3

Ajuda sobre o R

Figura 2: Abandonar o R.

1.3

Ajuda sobre o R
Obter ajuda no R

O R tem um sistema de ajuda bastante elaborado que lhe permitir obter muita informaa ca o extra sobre a linguagem, bem como muitos outros aspectos que lhe esto associados. a Nas verses Windows do R, a forma mais fcil de obter ajuda atravs da utilizao o a e e ca do menu Help dispon vel na janela da aplicao R. Atravs deste menu poss ca e e vel por exemplo, escolher a opo Html help o que far lanar um browser onde poder tirar ca a c a partido de uma srie de manuais e outros tipo de ajuda dispon e veis no R. No entanto, se pretende simplesmente obter ajuda sobre uma funo em particular ca do R, a forma mais simples ser provavelmente usar a funo help(), a ca > help(sqrt) Este comando ir fazer aparecer uma pequena janela com todo um conjunto de infora maes uteis sobre a funo escolhida, que vai da simples descrio dos seus argumentos co ca ca at exemplos de utilizao, bem como funes relacionadas. Em alternativa, poder e ca co a introduzir antes ? sqrt, produzindo exactamente o mesmo efeito. Quando no sabemos o nome concreto da funo sobre a qual preciamos de ajuda, a ca podemos usar como alternativas as funoes apropos() e help.search(). Genericamente, c ambas produzem uma lista das funes do R que contm referncias ao texto que incluimos co e e como argumento destas funes. Experimente por exemplo fazer, apropos(model), ou co help.search(model). Para dvidas mais complexas poder ainda consultar a muita documentao gratuita u a ca dispon vel no site do R (www.r-project.org), ou a mailing list de apoio dispon vel no mesmo site. Se optar por esta ultima alternativa recomenda-se que antes de colocar qualquer pergunta faa uma procura pelos arquivos da lista para evitar colocar questes c o j respondidas, o que nem sempre bem recebido pelas pessoas que se voluntariam para a e ajudar. Finalmente uma alternativa poderosa que junta vrias destas formas de ajuda do R a utilizar no R a funo RSiteSearch(). Esta funo faz lanar um browser que ir e ca ca c a mostrar o resultado da procura da string que passar como argumento ` funo. O a ca resultado da procura envolve toda a ajuda de todas as funes do R, ajuda nas mailing co lists, bem como em outros documentos. Por exemplo, se pretendo saber o que existe nestes locais sobre redes neuronais, poderia fazer a seguinte procura, > RSiteSearch('neural networks')

1.4 Packages do R
Uma instalao do R vem j com um conjunto de packages instaladas. Estas packages no ca a a so mais do que agregaes de funes que foram criadas por algum que as disponibilizou a co co e a ` comunidade de forma gratu Qualquer pessoa pode criar as suas packages e submetta. e las ao portal do R para que sejam consideradas na lista de packages dispon veis a . Quando se executa o R s algumas funes esto dispon o co a veis de imediato. Essas so a as funes inclu co das nas packages que foram julgadas mais importantes ou de uso mais comum e que so automaticamente carregadas quando se executa o R. Em qualquer a altura poderemos carregar uma package que contenha funes extra que necessitemos co para o nosso trabalho. Para tal ser poss vel a package dever estar instalada no nosso a computador. Se tal no fr o caso teremos que fazer o download da mesma e instal-la. a o a Este processo simples, desde que o seu computador esteja ligado ` Internet. e a

10

INTRODUCAO AO AMBIENTE R

Usar packages

Para instalar uma nova package podemos usar a funo install.packages(), que ca o leva como argumento o nome da package a instalar4 . Depois de indicado um repositrio de onde fazer o download da package o R ir encarregar-se de todo o processo, inclusiv a e da sua instalao no seu computador. ca Para utilizar packages que estejam dispon veis no seu sistema basta usar a funo ca library(), por exemplo, library(rpart) Esta instruo faz com que a partir de agora passem a estar dispon ca veis para utilizao, ca todos os objectos (funes, dados, etc.) denidos nessa package. Cada package instalada co tem uma ajuda espec ca que pode ser obtida no sistema de ajuda HTML do R que foi descrito na Seco 1.3. ca

Instalar novas packages

4 Na

realidade podemos instalar vrias indicando um vector (c.f. Seco 2.2) com nomes de packages. a ca

11

2
2.1

Fundamentos da Linguagem R
Os objectos do R

O R uma linguagem baseada em objectos. Isto quer dizer que tudo o que ns vamos e o usar no R est guardado na memria do computador sob a forma de um objecto. Todos a o os objectos em R tm um nome associado e podem armazenar diferentes tipos de coisas e (nmeros, texto, vectores, matrizes, expresses, chamadas a funes, etc.). u o co Para armazenar algo num objecto usamos o operador de atribuio. Este operador ca consiste num sinal < seguido por um sinal -, como se v no exemplo apresentado em see guida, em que guardamos o nmero 4.5 no objecto que resolvemos chamar taxa.de.juro, u > taxa.de.juro <- 4.5 Para ver o contedo de um objecto (o que est guardado na memria sob um deteru a o minado nome) basta digitar o nome do objecto no prompt do R, carregando em seguida em Enter. Como resposta o R mostra-nos o contedo do objecto que lhe indicamos. u Por exemplo, suponhamos que queremos conrmar o contedo do objecto taxa.de.juro, u > taxa.de.juro [1] 4.5 O estranho [1] que aparece antes do nmero guardado em taxa.de.juro, tem o u signicado esta linha est a mostrar o contedo de taxa.de.juro a comear no elemento a u c n 1 do objecto. O signicado disto tornar-se- mais bvio quando virmos objectos que a o podem armazenar mais do que um elemento, como por exemplo um vector contendo 100 nmeros. u A operao de atribuio destrutiva no sentido que ao atribuir um novo valor a um ca ca e objecto j existente, vamos perder o contedo que ele estava a armazenar anteriormente. a u > taxa.de.juro <- 3.9 > taxa.de.juro [1] 3.9 Tambm podemos atribuir expresses numricas a objectos. O resultado de tal opee o e rao o de que o resultado do clculo da expresso colocado no objecto, e no a ca e a a e a expresso propriamente dita, a > z <- 5 > w <- z^2 > w [1] 25 > i <- (z * 2 + 45)/2 > i [1] 27.5 Sempre que pretendemos atribuir o resultado de uma expresso a um objecto e em a seguida ver o seu contedo (como nos exemplos acima), podemos em alternativa usar a u seguinte sintaxe que nos poupa algum tempo, > (w <- z^2) [1] 25

Objectos do R

Operador de atribuio ca

Ver o conte do de u um objecto

Expresses o numricas e

12

FUNDAMENTOS DA LINGUAGEM R

Na realidade no necessrio atribuir o resultado das expresses a objectos. Isto s a e a o o far sentido se pretendermos usar o resultado do clculo mais tarde, por exemplo noutra a a expresso. Se pretendermos saber simplesmente o resultado do clculo, podemos usar o a a R como uma espcie de calculadora, e > (34 + 90)/12.5 [1] 9.92 Sempre que criamos um novo objecto usando a instruo de atribuio, ele ir car na ca ca a memria do computador. Como esta limitada, poderemos apagar os objectos sempre o e que no precisarmos mais deles. Podemos ver quais os objectos actualmente na memria a o do computador usando as funes ls() ou objects(). Se j no necessitamos de algum co a a dos objectos podemos ento apag-lo com a funo rm() como nos exemplos apresentados a a ca em seguida, > ls() [1] "i" > rm(taxa.de.juro) > rm(z, w) > objects() [1] "i"
Nomes vlidos a

O R como uma calculadora

Listar os objectos em memria o

"taxa.de.juro" "w"

"z"

O nome dos objectos pode ser formado por qualquer letra maiscula ou minscula, u u os d gitos 0 a 9 (excepto no in do nome), e tambm o ponto nal .. Os nomes dos cio e objectos em R so sens a veis `s letras maisculas / minsculas. Isto quer dizer que Cor a u u e cor so dois objectos diferentes para o R. Note tambm que no pode usar espaos a e a c nos nomes dos objectos. Por exemplo, se pretende ter um objecto que guarda uma determinada taxa de cmbio, poderia sentir-se tentado(a) a escolher o nome taxa de a cmbio para o objecto, o que iria gerar um erro do R, a > taxa de c^mbio <- 0.05 a Error: syntax error Em alternativa poderia usar o seguinte nome que j seria vlido, a a > taxa.de.c^mbio <- 0.05 a

2.2
O que um vector e

Vectores

Modo e tamanho dos vectores

O objecto mais bsico do R para guardar dados o vector. Um vector uma estrutura a e e de dados que permite armazenar um conjunto de valores do mesmo tipo (por exemplo nmeros) sob um mesmo nome. Esses elementos podem depois ser acedidos individuu almente usando um esquema de indexao que iremos descrever mais ` frente. Este ca a tipo de estrutura de dados bastante util quando pretendemos armazenar vrias coisas e a relacionadas na memria do computador. Por exemplo, suponhamos que pretendemos o guardar os lucros obtidos pela nossa empresa ao longo dos 12 meses do ano anterior. Em vez de termos 12 objectos diferentes, cada um guardando o lucro em cada ms, uma e vez que so nmeros relacionados uns com os outros, faz mais sentido guard-los todos a u a numa mesma estrutura de dados, que neste caso ser um vector com 12 nmeros. Em R, a u mesmo quando atribu mos um unico nmero a um objecto (por exemplo fazendo x < u 45), estamos de facto a criar um vector de nmeros com um unico elemento. u Todos os vectores em R tm um modo e um tamanho. O modo determina o tipo de e valores guardado no vector. Em R podemos ter vectores com modo character, logical, numeric e complex. Ou seja, podemos ter vectores para armazenar os seguintes tipos de dados atmicos: conjuntos de caracteres, valores lgicos (F ou T ou FALSE ou o o

2.2

Vectores

13

TRUE)5 , nmeros inteiros ou reais, e nmeros complexos. O tamanho de um vector u u e o nmero de elementos que ele contm, e pode ser obtido com a funo length(). u e ca Na maioria das situaes vamos criar vectores com mais do que um elemento. Para co isso precisamos de usar a funo c() para indicar ao R os elementos que formam o vector ca separando-os por v rgulas, > v <- c(4, 7, 23.5, 76.2, 80) > v [1] 4.0 7.0 23.5 76.2 80.0

Criar vectores

> length(v) [1] 5 > mode(v) [1] "numeric" Todos os elementos de um vector tm que ser do mesmo tipo (modo). Caso tentemos e criar um vector com elementos de tipo diferente o R vai for-los a ser do mesmo tipo, ca alterando-os. Vejamos um exemplo disso, > v <- c(4, 7, 23.5, 76.2, 80, "rrt") > v [1] "4" "7" "23.5" "76.2" "80" "rrt"

Coero de tipos ca

Porque um dos elementos do vector era do tipo caracter, o R passou todos os outros (que eram nmeros) para o tipo caracter, gerando assim um vector de conjuntos de u caracteres (strings). Isto quer dizer que por exemplo o primeiro elemento desse vector e a string 4 e no o nmero 4, o que tem como consequncia, por exemplo, no podermos a u e a usar este elemento numa expresso numrica. a e As strings em R so conjuntos de caracteres englobados por aspas ou plicas, a > w <- c("rrt", "ola", "isto e uma string") > w [1] "rrt" "ola" "isto e uma string"
Valores desconhecidos

Todos os vectores podem ter um elemento especial que o NA. Este valor representa e um valor desconhecido. Por exemplo, se temos os lucros trimestrais de uma empresa guardados num vector, mas por alguma razo desconhecemos o seu valor no terceiro a trimestre, poder amos usar a seguinte instruo para criar esse vector, ca > lucros <- c(234000, 245000, NA, 124500) > lucros [1] 234000 245000 NA 124500

Como j foi mencionado anteriormente, os elementos de um vector podem ser acedidos a atravs de um e ndice. Na sua forma mais simples este ndice um nmero indicando o e u elemento que pretendemos aceder. Esse nmero colocado entre parntesis rectos a u e e seguir ao nome do vector, > lucros[2] [1] 245000

Aceder a um elemento

14

FUNDAMENTOS DA LINGUAGEM R

Usando esta forma de aceder aos elementos individuais de um vector podemos alterar o contedo de um elemento particular de um vector, u > lucros[3] <- 45000 > lucros [1] 234000 245000
Vectores vazios

Alterar um elemen

45000 124500

O R permite-nos criar vectores vazios usando a funo vector(), ca > k <- vector()

Alterar tamanho de um vector

O tamanho de um vector j existente pode ser alterado atribuindo mais elementos a a ndices at agora inexistentes, e > k[3] <- 45 > k [1] NA NA 45 Repare que os dois primeiros elementos do vector k, que anteriormente era um vector vazio, caram com o valor NA ao colocarmos o valor 45 no terceiro elemento. Para diminuirmos o tamanho de um vector podemos usar a instruo de atribuio. ca ca Por exemplo, > v <- c(45, 243, 78, 343, 445, 645, 2, 44, 56, 77) > v [1] 45 243 78 343 445 645 2 44 56 77

> v <- c(v[5], v[7]) > v [1] 445 2

Atravs do uso de formas de indexao mais poderosas que iremos explorar na Sece ca co 2.6 vamos conseguir eliminar mais facilmente elementos particulares de um vector. a

2.3
Operaes com co vectores

Operaoes com Vectores c

Um dos aspectos mais poderosos da linguagem R a possibilidade de vectorizar a e maioria das suas funes. Isto quer dizer que a maioria das funes dispon co co veis no R , ao serem aplicadas a um vector, produzem como resultado um vector de resultados, que obtido aplicando a funo a cada um dos elementos do vector. Vejamos um exemplo e ca com a funo sqrt() que serve para calcular ra ca zes quadradas, > v <- c(4, 7, 23.5, 76.2, 80) > x <- sqrt(v) > x [1] 2.000000 2.645751 4.847680 8.729261 8.944272 Ao atribuir a x o resultado da aplicao da funo ao vector v, estamos de facto a ca ca criar um vector com as ra zes quadradas dos nmeros contidos em v. u Esta caracter stica do R pode ser usada para levar a cabo operaes aritmticas enco e volvendo vectores, > v1 <- c(4, 6, 87) > v2 <- c(34, 32.4, 12) > v1 + v2

2.4

Factores

15

[1] 38.0 38.4 99.0 O que acontece se tentamos realizar operaes envolvendo vectores de tamanho difeco rente? O R vai usar um regra de reciclagem dos valores do vector mais curto at este e atingir o tamanho do maior. Por exemplo, > v1 <- c(4, 6, 8, 24) > v2 <- c(10, 2) > v1 + v2 [1] 14 8 18 26

gra da reciclagem

E como se o vector c(10,2) fosse de facto c(10,2,10,2). Se os tamanhos no so a a mltiplos um do outro, o R imprime um aviso no cran, u e > v1 <- c(4, 6, 8, 24) > v2 <- c(10, 2, 4) > v1 + v2 [1] 14 8 12 34

Repare-se que um aviso no um erro, o que quer dizer que a operao foi levada a a e ca cabo. Como foi mencionado anteriormente, um nmero de facto armazenado em R como u e um vector de tamanho 1. Isto d bastante jeito para operaes como a seguinte, a co > v1 <- c(4, 6, 8, 24) > 2 * v1 [1] 8 12 16 48

Repare que o nmero 2 (de facto o vector c(2)!) foi reciclado at atingir o tamanho u e do vector v1, tendo como resultado a multiplicao dos elementos todos deste vector ca por 2. Como veremos mais tarde esta regra de reciclagem tambm se aplica a outros e objectos, como por exemplo matrizes.

2.4

Factores
Variveis nominais a (factores)

Os factores proporcionam uma forma fcil e compacta de lidar com dados categricos a o (ou nominais). Este tipo de dados podem ser vistos como variveis que podem tomar a como valores poss veis um conjunto nito de etiquetas (por exemplo uma varivel que a armazene o estado civil de uma pessoa). Os factores tm associados a eles um conjunto e de n veis que so os valores poss a veis que podem tomar. Como veremos mais tarde vrias a funes do R (por exemplo funes ligadas ` visualizao de dados) tiram partido do co co a ca facto de guardarmos informao categrica como factores em vez de usarmos strings. ca o Vejamos como criar factores em R. Suponhamos que pretendemos guardar o sexo de 10 indiv duos num vector, > s <- c("f", "m", "m", "m", "f", "m", "f", "m", "f", "f") > s [1] "f" "m" "m" "m" "f" "m" "f" "m" "f" "f" Ao transformarmos um vector de caracteres num factor, o R vai dar-nos a possibilidade de fazer coisas como por exemplo contar quantas vezes ocorre cada valor desse factor. Podemos transformar um vector de caracteres num factor da seguinte forma,
5 Como o R sens e vel `s letras maisculas / minsculas, True, por exemplo, no um valor lgico a u u a e o vlido. a

Criar factores

16

FUNDAMENTOS DA LINGUAGEM R

> s <- factor(s) > s [1] f m m m f m f m f f Levels: f m Repare que s deixou de ser um vector de caracteres6 . Neste pequeno exemplo, o nosso factor tem dois n veis, f e m. Suponha agora que temos 4 novos indiv duos cujo sexo tambm pretendemos armazee nar. Imagine que por coincidncia todos pertencem ao sexo masculino. Se pretendemos e que o factor resultante mantenha os 2 n veis poss veis para o sexo de um indiv duo teremos que fazer, > outro.s <- factor(c("m", "m", "m", "m"), levels = c("f", "m")) > outro.s [1] m m m m Levels: f m Sem o parmetro extra, indicando os n a veis a usar, a funo factor() iria dar origem ca a um factor com um unico n (m), uma vez que este o unico valor que ocorre no vel e vector de caracteres que estamos a transformar num factor. Conforme mencionado anteriormente, uma das vantagens de transformar um vector de caracteres num factor, a possibilidade de usar funes espec e co cas para lidar com factores. Uma dessas funes permite-nos contar o nmero de ocorrncias de cada valor co u e (n vel), > table(s) s f m 5 5 > table(outro.s) outro.s f m 0 4
Tabulaes cruzadas co

Contar ocorrncias e

A funo table() tambm pode ser usada para fazer tabulaes cruzadas de dois ca e co factores, desde que estes tenham o mesmo tamanho. Imaginemos que temos um outro vector com a gama de idades dos indiv duos cujo sexo est armazenado em s. Podemos a fazer uma tabulao cruzada da idade e do sexo dos 10 indiv ca duos, da seguinte forma, > idade <- factor(c("adulto", "adulto", "jovem", "jovem", "adulto", + "adulto", "adulto", "jovem", "adulto", "jovem")) > s [1] f m m m f m f m f f Levels: f m > idade [1] adulto adulto jovem Levels: adulto jovem > table(idade, s)
6 De facto, s um tipo especial de vector de n meros, uma vez que internamente, o R guarda os factores e u como vectores de nmeros, com tantos valores quantos os n u veis do factor. Isto pode ser conrmado fazendo mode(s).

jovem

adulto adulto adulto jovem

adulto jovem

2.4

Factores

17

s idade f m adulto 4 2 jovem 1 3 Isto quer dizer que existem 4 indiv duos que so adultos do sexo feminino, 2 que so a a homens adultos, etc. Repare como introduzimos a primeira instruo. Como era muito grande, mudamos ca de linha. Uma vez que o R descobre que a instruo ainda no est terminada, apresenta ca a a a linha seguinte com o prompt de continuao, que um sinal mais (+). ca e Tambm poss obter facilmente frequncias marginais e relativas. Por exemplo, e e vel e para saber o nmero total de adultos e jovens far u amos, > tabela.cruzada <- table(idade, s) > margin.table(tabela.cruzada, 1) idade adulto 6 jovem 4

Comandos espalhados por vrias linhas a Frequncias e marginais e relativas

Para obter a mesma informao relativamente ao sexo dos indiv ca duos, bastaria mudar o nmero 1, que indica que pretendemos os totais por linha (a primeira dimenso do u a objecto) da tabela cruzada, para um 2, para obtermos os totais por coluna da tabela cruzada, > margin.table(tabela.cruzada, 2) s f m 5 5 Relativamente a frequncias relativas, podemos usar a funo prop.table(), de cujo e ca uso apresentamos alguns exemplos, > prop.table(tabela.cruzada, 1) s idade f m adulto 0.6666667 0.3333333 jovem 0.2500000 0.7500000 > prop.table(tabela.cruzada, 2) s idade f m adulto 0.8 0.4 jovem 0.2 0.6 > prop.table(tabela.cruzada) s idade f m adulto 0.4 0.2 jovem 0.1 0.3 No primeiro exemplo, as propores so calculadas em relao ao total por linha. co a ca Assim, o nmero 0.6666667 o resultado de dividir 4 (o nmero de adultos femininos), u e u por 6 (o nmero total de adultos). No segundo exemplo, as propores so relativamente u co a aos totais por coluna, enquanto que no terceiro exemplo so relativas ao nmero total a u de indiv duos (isto , camos a saber que o nmero de adultos masculinos representa e u 20% do total dos indiv duos). Caso pretendssemos, obter os nmero em percentagem, e u poder amos simplesmente multiplicar as chamadas `s funes pelo nmero 1007 , a co u
7 Rera-se

a t tulo de curiosidade que isto mais um exemplo da regra de reciclagem. e

18

FUNDAMENTOS DA LINGUAGEM R

> 100 * prop.table(tabela.cruzada) s idade f m adulto 40 20 jovem 10 30

2.5
Gerar sequncias de e inteiros

Sequncias e

Podem-se gerar sequncias em R de vrias formas. Por exemplo, imaginemos que pree a tendemos criar um vector com os nmero de 1 a 1000. Em vez de os escrevermos todos, u podemos usar, > x <- 1:1000 o que cria um vector com os nmero inteiros de 1 a 1000. u Devemos ter algum cuidado com a precedncia do operador :, que usado para e e gerar sequncias, em relao aos operadores aritmticos. O exemplo seguinte ilustra os e ca e perigos que corremos, > 10:15 - 1 [1] 9 10 11 12 13 14

> 10:(15 - 1) [1] 10 11 12 13 14 Repare o que aconteceu no primeiro exemplo. Devido ao operador : ter maior precedncia do que o -, o R gerou um vector com os nmeros de 10 a 15 e depois e u subtraiu a esse vector o nmero 1. Devido ` regra da reciclagem isto correspondeu a u a subtrair 1 a todos os elementos do vector, levando ao resultado que vemos acima. J no a segundo exemplo, usamos os parntesis para indicar ao R que o que pretendemos um e e vector contendo os nmeros desde 10 at ao resultado da operao 15-1, i.e. 14. u e ca O operador : tambm pode ser usado para gerar sequncias descendentes, e e > 5:0 [1] 5 4 3 2 1 0
Sequncias de reais e

Sequncias e descendentes

Para gerar sequncias com nmeros reais podemos usar a funo seq(), e u ca > seq(-4, 1, 0.5) [1] -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0

No exemplo acima geramos uma sequncia formada pelos nmeros a comear em e u c -4 at 1 de 0.5 em 0.5. Esta funo tem vrias outras possibilidades para explicitar e ca a a sequncia que pretendemos. Alguns exemplos so dados a baixo. Poder tambm e a a e explorar as potencialidades de ajuda do R, digitando o comando ? seq que mostra o help relativamente ` funo seq. a ca > seq(from = 1, to = 5, length = 4) [1] 1.000000 2.333333 3.666667 5.000000 > seq(from = 1, to = 5, length = 2) [1] 1 5 > seq(length = 10, from = -2, by = 0.2)

2.5

Sequncias e

19

[1] -2.0 -1.8 -1.6 -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2 Repare que existe uma diferena subtil na forma como usamos as funo seq() nos c ca exemplos acima. De facto, em vez de indicarmos os valores dos argumentos da funca o (como por exemplo em seq(-4,1,0.5), indicamos o nome dos argumentos seguido de um sinal igual e o valor com o qual pretendemos chamar a funo. As duas forca mas so equivalentes, no entanto a chamada por nome tem vantagens de legibilidade a e tambm quando a funo tem muitos argumentos permite-nos desrespeitar a sua ore ca dem, ou seja, relativamente aos exemplos anteriores obter amos o mesmo resultado com seq(length=4,from=1,to=5). Iremos analisar com mais detalhe esta questo quando a estudarmos o uso e criao de funes em R na Seco 3.3.1. ca co ca Uma outra funo bastante util para gerar sequncias a funo rep(), ca e e ca > rep(5, 10) [1] 5 5 5 5 5 5 5 5 5 5 > rep("sim", 3) [1] "sim" "sim" "sim" > rep(1:3, 2) [1] 1 2 3 1 2 3 A funo gl() pode ser usada para gerar sequncias envolvendo factores. A sintaxe ca e desta funo gl(k,n), em que k o nmero de n ca e e u veis do factor e n o nmero de u repeties de cada n co vel. Vejamos dois exemplos, > gl(3, 5) [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 Levels: 1 2 3 > gl(2, 5, labels = c("nao", "sim")) [1] nao nao nao nao nao sim sim sim sim sim Levels: nao sim Finalmente, o R tem uma srie de funes para gerar sequncias aleatrias de acordo Sequncias e co e o e com uma srie de funes de distribuio de probabilidade. Essas funes tm a forma ge- aleatrias e co ca co e o nrica rfunc(n, par1, par2, ...), em que n o nmero de dados a gerar, e par1, par2, ... e e u so valores de alguns parmetros que a funo espec a a ca ca a ser usada possa precisar. Por exemplo, se pretendemos 10 nmeros gerados aleatoriamente de acordo com uma distriu buio normal de mdia 0 e desvio padro unitrio, podemos fazer, ca e a a > rnorm(10) [1] [7] 0.6068968 0.2129164 1.2468432 1.8680112 0.8129556 -0.1786157 1.3694861 -2.7365075 -0.8887380 0.7735804
Sequncias com e factores

omes dos

gumentos

Sequncias repetidas e

Se preferirmos 10 nmeros provenientes de uma distribuio normal com mdia 10 e u ca e desvio padro 3, far a amos > rnorm(10, mean = 10, sd = 3) [1] 11.224101 12.993983 [8] 8.388759 11.020737 9.577280 4.095438 8.083312 7.553354 13.085718 8.347373

De igual modo para obter 5 nmeros obtidos de forma aleatria de uma distribuio u o ca t de Student com 10 graus de liberdade, fazemos

20

FUNDAMENTOS DA LINGUAGEM R

> rt(5, df = 10) [1] 1.1357666 -2.7568824 0.7445925 -0.3963767 1.2472630

O R tem muitas mais funes para outras distribuies de probabilidade, bem como co co funes semelhantes para obter a densidade de probabilidade, as densidades acumuladas co e os quartis das distribuies. No entanto, a explorao exaustiva destas funes sai co ca co fora do mbito desta cadeira, podendo o aluno por exemplo obter mais informao no a ca a co e livro Dalgaard (2002), ou ento consultando a ajuda das funes que contm exemplos e referncias a funes relacionadas. e co

2.6

Indexao ca

Vectores de ndices Vector de ndices lgicos o

Na Seco 2.2 j vimos exemplos de como extrair um elemento de um vector indicando a ca a sua posio entre parntesis rectos. O R tambm nos permite usar vectores dentro desses ca e e parntesis rectos. Estes vectores chamam-se vectores de e ndices. Existem vrios tipos de a vectores de ndices. Os vectores de ndices booleanos extraem de um vector os elementos correspondentes a posies verdadeiras. Vejamos um exemplo concreto, co > x <- c(0, -3, 4, -1, 45, 90, -5) > x [1] 0 -3 4 -1 45 90 -5

> x > 0 [1] FALSE FALSE > y <- x > 0 A terceira instruo do cdigo mostrado acima uma condio lgica envolvendo ca o e ca o o vector x. Esta condio uma comparao com o valor zero. Devido ` regra de ca e ca a reciclagem, o resultado desta comparao um vector de valores lgicos resultantes de ca e o fazer a comparao para cada elemento do vector x. Na instruo seguinte guardamos ca ca este vector lgico no objecto y. Usando este vector como um vector de o ndices, podemos obter os elementos de x que so maiores do que zero, da seguinte forma, a > x[y] [1] 4 45 90 TRUE FALSE TRUE TRUE FALSE

Como os elementos de y que so verdadeiros (true) so o 3, 5 e o 6, isto corresa a ponde a extrair esses elementos de x, que o resultado que obtemos com a instruo e ca mostrada acima. Poder amos obter um resultado igual, evitando criar um novo vector, fazendo > x[x > 0] [1] 4 45 90

Tirando partido da gama de operadores lgicos dispon o veis no R, podemos construir vectores de indexao lgicos mais complexos, ca o > x[x <= -2 | x > 5] [1] -3 45 90 -5 > x[x > 40 & x < 100] [1] 45 90

2.6

Indexao ca

21

peradores lgicos o

O operador | corresponde ao OU (disjuno) lgico, enquanto o operador & o ca o e E (conjuno) lgica. Isto quer dizer que a primeira instruo d como resultado os ca o ca a elementos de x que so menores ou iguais a -2, ou maiores do que 5. O segundo exemplo, a por sua vez, mostra-nos os elementos de x que so maiores do que 40 e menores do que a 100. Note que existem duas variantes destes dois operadores lgicos com um modo de o funcionamento ligeiramente diferente. Eles so os operadores || e &&. Ambos fazem a as mesmas operaes que os anteriores, o OU e o E lgicos. A diferena reside no facto co o c de os operadores anteriores fazerem essas operaes de forma vectorial, ou seja elemento co a elemento quando os operandos contm mais do que um elemento, o que permite por e exemplo aplicar as operaes sobre conjuntos de nmeros, como nos exemplos mostrados co u em cima. Ou seja estes operadores produzem um conjunto de resultados (valores T ou F). J as variantes com dois s a mbolos, s fazem a operao sobre o primeiro elemento, ou o ca seja procedem da esquerda para a direita, produzindo um unico resultado. Estas ultimas variantes so essencialmente usadas em instrues de controlo da execuo de programas, a co ca como iremos ver na Seco 3.2.1. ca O R tambm nos permite usar um vector de nmeros inteiros como e u ndice de um outro vector. Os nmeros desse vector de u ndices correspondem aos elementos a extrair do outro vector, > (v <- c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")) [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" > v[c(4, 6)] [1] "d" "f" > v[1:3] [1] "a" "b" "c" Podemos ainda usar um vector com nmeros negativos, o que nos permite indicar u quais os elementos a no obter como resultado da indexao, a ca > v[-1] [1] "b" "c" "d" "e" "f" "g" "h" "i" "j" > v[-c(4, 6)] [1] "a" "b" "c" "e" "g" "h" "i" "j" > v[-(1:3)] [1] "d" "e" "f" "g" "h" "i" "j" Note bem a importncia dos parntesis no ultimo exemplo, devido ` precedncia do a e a e operador : j mencionada na Seco 2.5. a ca Um vector tambm pode ser indexado por um vector de strings tirando partido do e facto de o R permitir dar nomes aos elementos de um vector atravs na funo names(). e ca Vectores com os elementos com nomes so por vezes prefer a veis pois as suas posies co so mais facilmente memorizveis. Suponhamos que t a a nhamos um vector com as taxas de inao de 5 pa ca ses europeus. Poder amos criar um vector com nomes da seguinte forma, > tx.infl <- c(2.5, 2, 2.1, 2.3, 1.9) > names(tx.infl) <- c("Portugal", "Frana", "Espanha", "Itlia", c a + "Alemanha") > tx.infl

Vector de ndices numricos e

Indices negativos

Indices com nomes

Dar nomes a elementos de vectores

22

FUNDAMENTOS DA LINGUAGEM R

Portugal 2.5

Frana c 2.0

Espanha 2.1

Itlia Alemanha a 2.3 1.9

Os elementos do vector tx.in podem agora ser acedidos usando os seus nomes, > tx.infl["Portugal"] Portugal 2.5 > tx.infl[c("Espanha", "Alemanha")] Espanha Alemanha 2.1 1.9
Indices vazios

Finalmente, os ndices podem ser vazios, o que tem o signicado que todos os elementos so seleccionados. Por exemplo, se pretendemos preencher todas as posies de um a co vector com zeros podemos fazer x[] <- 0. De notar, que isto diferente de fazer x <e 0, que teria como efeito atribuir ao vector x um vector com um unico elemento (zero), enquanto que a primeira alternativa, assumindo que o vector x j existia, iria substituir a todos os seus elementos por zero. Tente ambas as alternativas.

2.7
O que uma matriz e

Matrizes

Criar uma matriz

Por vezes poderemos estar interessados em armazenar a nossa informao em estruturas ca de dados com mais do que uma dimenso, como o caso dos vectores. As matrizes arrana e jam a informao em duas dimenses. Em R, as matrizes no so mais do que vectores ca o a a com uma propriedade especial que a dimenso. Vejamos um exemplo. Suponhamos que e a temos doze nmeros correspondentes `s vendas trimestrais durante o ultimo ano, em trs u a e lojas. As instrues seguintes permitem organizar esses nmeros como uma matriz, co u > vendas <- c(45, 23, 66, 77, 33, 44, 56, 12, 78, 23, 78, 90) > vendas [1] 45 23 66 77 33 44 56 12 78 23 78 90 > dim(vendas) <- c(3, 4) > vendas [,1] [,2] [,3] [,4] 45 77 56 23 23 33 12 78 66 44 78 90

[1,] [2,] [3,]

Repare como os nmeros foram espalhados por uma matriz com 3 linhas e 4 colunas, u que foi a dimenso que atribu a mos ao vector vendas atravs da funo dim(). Na e ca realidade seria mais simples criar a matriz usando uma funo espec ca ca para isso, > vendas <- matrix(c(45, 23, 66, 77, 33, 44, 56, 12, 78, 23, 78, + 90), 3, 4) Como eventualmente ter reparado os nmeros foram espalhados pela matriz por a u coluna, i.e. primeiro foi preenchida a primeira coluna, depois a segunda, etc. Caso no a seja isto o que pretendemos, poderemos preencher a matriz por linhas da seguinte forma, > vendas <- matrix(c(45, 23, 66, 77, 33, 44, 56, 12, 78, 23, 78, + 90), 3, 4, byrow = T) > vendas

2.7

Matrizes

23

[1,] [2,] [3,]

[,1] [,2] [,3] [,4] 45 23 66 77 33 44 56 12 78 23 78 90

Nas matrizes tambm poss dar nomes aos elementos para tornar a leitura da ine e vel formao mais leg ca vel. Vejamos como fazer isso para a nossa matriz de vendas trimestrais nas 3 lojas, > rownames(vendas) <- c("loja1", "loja2", "loja3") > colnames(vendas) <- c("1.trim", "2.trim", "3.trim", "4.trim") > vendas 1.trim 2.trim 3.trim 4.trim 45 23 66 77 33 44 56 12 78 23 78 90

Dar nomes `s linhas a e colunas

loja1 loja2 loja3

Como a visualizao das matrizes sugere, podemos aceder aos elementos individuais ca das matrizes usando um esquema de indexao semelhante ao dos vectores, mas desta ca vez com dois ndices (as dimenses da matriz), o > vendas[2, 2] [1] 44 Ou ento, tirando partido dos nomes, a > vendas["loja2", "2.trim"] [1] 44 De igual modo, podemos tirar partido dos esquemas de indexao discutidos na Secca ca o 2.6 para seleccionar elementos das matrizes, como mostram os seguintes exemplos, > vendas[-2, 2] loja1 loja3 23 23 > vendas[1, -c(2, 4)] 1.trim 3.trim 45 66 Podemos mesmo omitir uma das dimenses das matrizes para deste modo obter todos o os elementos da mesma (um ndice vazio), > vendas[1, ] 1.trim 2.trim 3.trim 4.trim 45 23 66 77 > vendas[, "4.trim"] loja1 loja2 loja3 77 12 90 As funes cbind() e rbind() podem ser usadas para juntar dois ou mais vectores co ou matrizes, por colunas ou por linhas, respectivamente. Os seguintes exemplos ilustram o seu uso,

Aceder aos elementos da matriz

24

FUNDAMENTOS DA LINGUAGEM R

> m1 <- matrix(c(45, 23, 66, 77, 33, 44, 56, 12, 78, 23), 2, 5) > m1 [,1] [,2] [,3] [,4] [,5] 45 66 33 56 78 23 77 44 12 23

[1,] [2,]

> cbind(c(4, 76), m1[, 4]) [,1] [,2] 4 56 76 12

[1,] [2,]

> m2 <- matrix(rep(10, 50), 10, 5) > m2 [,1] [,2] [,3] [,4] [,5] 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10

[1,] [2,] [3,] [4,] [5,] [6,] [7,] [8,] [9,] [10,]

> m3 <- rbind(m1[1, ], m2[5, ]) > m3 [,1] [,2] [,3] [,4] [,5] 45 66 33 56 78 10 10 10 10 10

[1,] [2,]

Reciclagem com matrizes

As regras aritmticas e de reciclagem que estudamos anteriormente, tambm se aplie e cam `s matrizes. Vejamos uns pequenos exemplos, a > m <- matrix(c(45, 23, 66, 77, 33, 44, 56, 12, 78, 23), 2, 5) > m [,1] [,2] [,3] [,4] [,5] 45 66 33 56 78 23 77 44 12 23

[1,] [2,]

> m * 3 [,1] [,2] [,3] [,4] [,5] 135 198 99 168 234 69 231 132 36 69

[1,] [2,]

> m1 <- matrix(c(45, 23, 66, 77, 33, 44), 2, 3) > m1 [,1] [,2] [,3] 45 66 33 23 77 44

[1,] [2,]

> m2 <- matrix(c(12, 65, 32, 7, 4, 78), 2, 3) > m2

2.7

Matrizes

25

[1,] [2,]

[,1] [,2] [,3] 12 32 4 65 7 78

> m1 + m2 [,1] [,2] [,3] 57 98 37 88 84 122

[1,] [2,]

A aplicao das operaes a matrizes (como no exemplo > m*3 apresentado acima), ca co funciona elemento a elemento como no caso dos vectores. Isto signica que se um operando menor ele reciclado at perfazer o tamanho do maior. No entanto, o R tambm e e e e possui operadores especiais para as usuais operaes da lgebra matricial. Por exemplo co a a multiplicao de duas matrizes pode ser feita da seguinte forma, ca > m1 <- matrix(c(45, 23, 66, 77, 33, 44), 2, 3) > m1 [,1] [,2] [,3] 45 66 33 23 77 44

Multiplicao ca matricial

[1,] [2,]

> m2 <- matrix(c(5, 3, 466, 54.5, 3.2, -34), 3, 2) > m2 [,1] [,2] 5 54.5 3 3.2 466 -34.0

[1,] [2,] [3,]

> m1 %*% m2 [,1] [,2] [1,] 15801 1541.7 [2,] 20850 3.9 Atente no operador especial (%*%) para simbolizar que se trata da multiplicao maca tricial e no a usual multiplicao. A multiplicao matricial tem, como sabido, regras a ca ca e especiais no que concerne, por exemplo, ` dimenso das matrizes envolvidas, pelo que a a no poder ser usada com quaisquer matrizes. a a Ainda no contexto da lgebra matricial, o R tem muitas outras funes, como por a co exemplo a funo t() para obter a transposta de uma matriz quadrada, ca > t(m1) [,1] [,2] 45 23 66 77 33 44
Determinante de uma matriz

Transposta de uma matriz

[1,] [2,] [3,]

ou a funo det() para calcular o determinante de uma matriz, ca > m <- matrix(c(34, -23, 43, 5), 2, 2) > det(m) [1] 1159 E tambm poss usar a funo solve() para obter a inversa de uma matriz, e vel ca

Inversa de uma matriz

26

FUNDAMENTOS DA LINGUAGEM R

> solve(m) [,1] [,2] [1,] 0.004314064 -0.03710095 [2,] 0.019844694 0.02933563
Resolver sistemas de equaes co

Finalmente, esta mesma funo pode ser usada para resolver sistemas de equaes ca co lineares. Imaginemos o seguinte sistema de equaes, co 4x + 0.3y = 54.3x 4y = Podemos resolv-lo em R da seguinte forma, e 12.3 45

> coefs <- matrix(c(-4, 0.3, 54.3, -4), 2, 2, byrow = T) > ys <- c(12.3, 45) > solve(coefs, ys) [1] 216.2069 2923.7586

2.8

Arrays

Criar arrays

Os arrays so extenses das matrizes para mais do que duas dimenses. Isto signica a o o ` c que podem ter vrios a ndices. A parte esta pequena diferena, eles podem ser usados da mesma forma do que as matrizes. De modo semelhante ` funo matrix, existe uma a ca funo array() para facilitar a criao de arrays. Segue-se um pequeno exemplo, ca ca > a <- array(1:50, dim = c(2, 5, 5)) > a , , 1 [,1] [,2] [,3] [,4] [,5] 1 3 5 7 9 2 4 6 8 10

[1,] [2,]

, , 2 [,1] [,2] [,3] [,4] [,5] 11 13 15 17 19 12 14 16 18 20

[1,] [2,]

, , 3 [,1] [,2] [,3] [,4] [,5] 21 23 25 27 29 22 24 26 28 30

[1,] [2,]

, , 4 [,1] [,2] [,3] [,4] [,5] 31 33 35 37 39 32 34 36 38 40

[1,] [2,]

, , 5 [,1] [,2] [,3] [,4] [,5] 41 43 45 47 49 42 44 46 48 50

[1,] [2,]
Indexar arrays

Os esquemas usuais de indexao que vimos para vectores e matrizes, podem tambm ca e ser aplicados aos arrays.

2.9

Listas

27

2.9

Listas
O que uma lista e

Uma lista uma coleco ordenada de objectos conhecidos como os componentes da e ca lista. Esses componentes no necessitam de ser do mesmo tipo, modo ou tamanho. Os a componentes de uma lista em R so sempre numerados e podem tambm ter um nome a e associados a eles. Vejamos um pequeno exemplo de criao de uma lista em R, ca > estudante <- list(nro = 34453, nome = "Carlos Silva", notas = c(14.3, + 12, 15, 19)) O objecto estudante uma lista formada por trs componentes. Um um nmero e e e u e tem o nome nro, outro uma string e tem o nome nome, e o terceiro componente e e um vector de nmeros com o nome notas. u Podemos extrair componentes espec cos de uma lista atravs da seguinte sintaxe, e > estudante[[1]] [1] 34453 > estudante[[3]] [1] 14.3 12.0 15.0 19.0 Como certamente ter reparado, usamos parntesis rectos duplos. Se, por exema e plo, tivssemos indicado estudante[1], ter e amos obtido um resultado diferente. Neste ultimo caso ter amos uma sub-lista formada pelo primeiro componente da lista estudante. Pelo contrrio, estudante[[1]] obtm o contedo do primeiro componente da a e u lista estudante, que neste caso um nmero, e logo no uma lista. e u a e No caso de listas com componentes com nomes, como o caso da lista estudante, podemos extrair os componentes da lista usando uma forma alternativa, > estudante$nro [1] 34453 Podemos ver todo o contedo da lista (como alis de qualquer objecto no R), escreu a vendo o seu nome, > estudante $nro [1] 34453 $nome [1] "Carlos Silva" $notas [1] 14.3 12.0 15.0 19.0 Os nomes dos componentes de uma lista so de facto uma propriedade da lista e a portanto podemos manipul-los como zemos com os nomes dos elementos de um vector, a > names(estudante) [1] "nro" "nome" "notas"

Criar uma lista

Extrair componentes de uma lista

Mostrar conte do u da lista

> names(estudante) <- c("nmero", "nome", "notas") u > estudante

28

FUNDAMENTOS DA LINGUAGEM R

$nmero u [1] 34453 $nome [1] "Carlos Silva" $notas [1] 14.3 12.0 15.0 19.0
Extender listas

As listas podem ser extendidas acrescentando-lhes novos componentes, > estudante$pais <- c("Ana Castro", "Miguel Silva") > estudante $nmero u [1] 34453 $nome [1] "Carlos Silva" $notas [1] 14.3 12.0 15.0 19.0 $pais [1] "Ana Castro"

"Miguel Silva"

N mero de u componentes de uma lista

Podemos saber quantos componentes tem uma lista usando a funo length(), ca > length(estudante) [1] 4

Juntar listas

Podemos juntar duas ou mais listas numa s usando a funo c(), o ca > resto <- list(idade = 19, sexo = "masculino") > estudante <- c(estudante, resto) > estudante $nmero u [1] 34453 $nome [1] "Carlos Silva" $notas [1] 14.3 12.0 15.0 19.0 $pais [1] "Ana Castro" $idade [1] 19 $sexo [1] "masculino"

"Miguel Silva"

2.10

Data Frames

29

2.10

Data Frames

que um data e

me

Um data frame um objecto do R que normalmente usado para guardar tabelas de e e dados de um problema qualquer. Na sua forma, um data frame, muito semelhante a e uma matriz, mas as suas colunas tm nomes e podem conter dados de tipo diferente, e contrriamente a uma matriz. Um data frame pode ser visto como uma tabela de uma a base de dados, em que cada linha corresponde a um registo (linha) da tabela. Cada coluna corresponde `s propriedades (campos) a serem armazenadas para cada registo da a tabela. Podemos criar um data frame da seguinte forma, > notas.inform <- data.frame(nros = c(2355, 3456, 2334, 5456), + turma = c("tp1", "tp1", "tp2", "tp3"), notas = c(10.3, 9.3, + 14.2, 15)) > notas.inform 1 2 3 4 nros turma notas 2355 tp1 10.3 3456 tp1 9.3 2334 tp2 14.2 5456 tp3 15.0 Os elementos de um data frame podem ser acedidos como uma matriz, > notas.inform[2, 2] [1] tp1 Levels: tp1 tp2 tp3 Atente no facto que a funo data.frame() transformou a coluna turma num factor. ca Isto feito sempre que os elementos de uma coluna sejam todos do tipo string, como o e e caso. Os esquemas de indexao descritos na Seco 2.6 tambm podem ser usados com ca ca e os data frames. Adicionalmente, as colunas dos data frames podem ser acedidas na sua totalidade usando o seu nome, > notas.inform$nros [1] 2355 3456 2334 5456 Usando os esquemas de indexao envolvendo condies lgicas, que foram descritos ca co o na Seco 2.6, podemos fazer consultas mais complexas aos dados guardados num data ca frame. Prosseguindo a analogia com tabelas de bases de dados, os exemplos seguintes podem ser visto como queries a uma tabela, > notas.inform[notas.inform$notas > 10, ] nros turma notas 1 2355 tp1 10.3 3 2334 tp2 14.2 4 5456 tp3 15.0 > notas.inform[notas.inform$notas > 14, "nros"] [1] 2334 5456 > notas.inform[notas.inform$turma == "tp1", c("nros", "notas")] nros notas 1 2355 10.3 2 3456 9.3

Criar um data frame

Aceder aos elementos de um data frame

Indexar data frames

30

FUNDAMENTOS DA LINGUAGEM R

As consultas a data frames apresentadas acima, podem ser simplicadas atravs do e uso da funo attach(). Sem entrar em detalhes tcnicos, podemos dizer que esta ca e funo nos permite aceder directamente aos valores nas colunas de um data frame sem ca para isso necessitarmos de colocar o nome deste atrs do nome da coluna, como foi feito a nos exemplos acima. Vejamos como isto funciona, > attach(notas.inform)

As funes attach( co e detach()

The following object(s) are masked from notas.inform ( position 4 ) : notas nros turma > notas.inform[notas > 14, ] nros turma notas 3 2334 tp2 14.2 4 5456 tp3 15.0 > turma [1] tp1 tp1 tp2 tp3 Levels: tp1 tp2 tp3 O efeito da funo attach() o mesmo que se obteria se crissemos uns objectos com ca e a o nome das colunas, contendo os dados das mesmas (por exemplo fazendo > notas <notas.inform$notas). A funo detach() tem o efeito inverso, e deve ser executada ca quando j no precisamos mais deste acesso directo `s colunas, a a a > detach(notas.inform) > turma Error: Object "turma" not found Repare que se a seguir a fazermos o detach tentarmos usar os nomes das colunas, como o zemos anteriormente, vamos gerar um erro, como se v no exemplo acima. e E poss acrescentar novas colunas a um data frame, vel > notas.inform$resultado <- c("aprovado", "oral", "aprovado", "aprovado") > notas.inform 1 2 3 4
N mero de linhas e u colunas

Acrescentar colunas a um data frame

nros turma notas resultado 2355 tp1 10.3 aprovado 3456 tp1 9.3 oral 2334 tp2 14.2 aprovado 5456 tp3 15.0 aprovado

A unica restrio a este tipo de acrescentos a de que a nova coluna dever ter tantos ca e a elementos quantas as linhas do data frame. Podemos saber o nmero de linhas e colunas u de um data frame da seguinte forma, > nrow(notas.inform) [1] 4 > ncol(notas.inform) [1] 4 Como veremos em seces posteriores deste texto de apoio, na maioria dos casos co no iremos escrever os dados a guardar num data frame ` mo usando a funo a a a ca data.frame(), como zemos anteriormente. De facto, na maioria das situaes iremos co buscar os nossos dados ou a uma base de dados, ou a um cheiro de texto, ou mesmo a uma fonte de dados dispon na Internet. De qualquer modo, sempre que pretendemos vel introduzir ns prprios os dados podemos usar um interface tipo folha de clculo que o o o a R possui, para facilitar a nossa tarefa. Vejamos como,

Introduzir dados num data frame

2.11

Sries Temporais e

31

> outras.notas <- data.frame() > outras.notas <- edit(outras.notas) A primeira instruo serve para dizer ao R que o objecto outras.notas um data ca e frame (vazio de dados, neste momento). A segunda instruo invoca o referido interface ca tipo folha de clculo com esse objecto, e coloca o resultado da nossa edio nesse mesmo a ca objecto, ou seja as alteraes que zermos na folha de clculo sero armazenadas no co a a objecto outras.notas. O interface da funo edit() permite-nos acrescentar facilmente ca valores nas colunas do data frame bastando para isso clicar em cima de uma clula e e comear a escrever o seu valor, bem como dar nomes `s colunas do data frame, clicando c a em cima do seu nome. Experimente.

2.11

Sries Temporais e

Existem inmeras aplicaes onde os dados que so recolhidos esto etiquetados pelo u co a a tempo. Quer isto dizer que existe uma ordem temporal entre as diferentes observaes co de uma ou mais variveis. Estes tipos de dados so normalmente conhecidos como sries a a e temporais. Uma srie temporal (univariada) um conjunto de observaes de uma varivel Y ao e e co a longo do tempo, y1 , y2 , . . . , yt1 , yt . Conforme seria previs o R tem vrias facilidades vel a para lidar com este tipo de dados. Na nossa exposio vamos distinguir dois tipos de ca sries: regulares e irregulares. Este tipo de sries vo ser armazenados em objectos de e e a diferente tipo em R, conforme vamos ver. 2.11.1 Sries Regulares e

O que uma srie e e temporal?

Numa srie temporal regular todas as observaes esto igualmente espaadas no tempo. e co a c Quer isto dizer que a diferena temporal entre quaisquer duas observaes sempre a c co e mesma. Para este tipo de dados o R disponibiliza os objectos da classe ts ou mts, para sries e multivariadas. Este tipo de objectos permite guardar dados referentes a sries temporais e regulares. Vejamos exemplos da criao deste tipo de objectos: ca > ts(rnorm(10), start = 1990, frequency = 1) Time Series: Start = 1990 End = 1999 Frequency = 1 [1] -0.007145366 0.286113853 -0.178509296 1.110593387 -0.537384054 [6] 0.235266885 -0.347034238 0.186546117 -0.560699688 -0.939207908 > ts(rnorm(10), frequency = 4, start = c(1959, 2)) Qtr1 Qtr2 Qtr3 1959 -0.06177427 -0.39010380 1960 -0.52024659 0.79999330 0.11223208 1961 2.64958972 0.27428917 1.44606713 Qtr4 0.52328884 1.08645298

Sries regulares e

Criar sries e regulares

> ts(rnorm(10), frequency = 12, start = c(1959, 2)) Feb Mar Apr May 1.86124434 -1.21152214 -1.25001426 -0.65898372 Aug Sep Oct Nov 1959 -1.82540080 -0.02475364 1.51389043 -1.20735747 1959 Jun Jul 0.87284088 -1.32159856

Como vemos, a funo principal para criar este tipo de objectos a funo ts(). Esta ca e ca funo recebe no primeiro argumento as observaes da srie e depois tem um conjunto de ca co e argumentos que podem ser usados para explicitar os intervalos de tempo regulares a que

32

FUNDAMENTOS DA LINGUAGEM R

Sries multivariadas e

se observaram esses valores. Assim no primeiro exemplo, indicamos que o primeiro valor observado no tempo 1990 e que entre cada unidade de tempo (i.e. 1990, 1991, 1992, e etc., uma vez que assumido um incremento de 1 entre as unidades de tempo) a varivel e a amostrada uma unica vez. J no segundo exemplo, indicamos que a srie comea no e a e c segundo per odo de amostragem da unidade de tempo 1959, e que a srie amostrada e e 4 vezes entre cada unidade. Isto leva o R a interpretar esta srie como uma srie de e e valores trimestrais, o que por sua vez determina a escolha de uma forma adequada para representar esta srie. No ultimo exemplo, indicamos que a srie amostrada 12 vezes e e e entre cada unidade de tempo o que leva o R a assumir amostragens mensais entre cada ano, e mais uma vez determina uma maneira adequada de a representar. No caso de sries multivariadas podemos cri-las de igual forma: e a > (m <- ts(matrix(rnorm(30), 10, 3), start = c(1961, 6), frequency = 12)) Series 1 -0.59624245 0.29513818 0.61927156 -0.04721077 -1.20085735 -0.85436753 -1.21451369 -0.44169035 0.91459593 -0.36624088 Series 2 1.0808275 -0.9746566 -0.1127870 1.0725438 0.1319664 0.3550235 -1.6505330 0.4167947 0.1500598 -0.2471749 Series 3 0.5293899 -0.7295948 1.2087357 1.1728149 0.4304150 -0.9931418 -1.1396180 0.6371993 -0.6730498 0.6283073

Jun Jul Aug Sep Oct Nov Dec Jan Feb Mar R.
Grcos de sries a e

1961 1961 1961 1961 1961 1961 1961 1962 1962 1962

Repare como foram tratadas de maneira diferente, em termos de apresentao, pelo ca Relativamente ` representao grca das sries temporais, podemos usar de igual a ca a e modo a muitos objectos, a funo plot(), como vemos no seguinte exemplo, ca > k <- ts(rnorm(100), frequency = 4, start = c(1959, 2)) > plot(k) que produz o grco apresentado na Figura 3. a

k 2 1960 1

1965

1970 Time

1975

1980

Figura 3: Grco de uma srie temporal univariada. a e No caso de o objecto em cause ser uma srie multivariada a funo plot() produz e ca grcos separados para cada srie como vemos na Figura 4. a e > m <- ts(matrix(rnorm(300), 100, 3), start = c(1961, 6), frequency = 12) > plot(m)

2.11

Sries Temporais e

33

m
2

Series 1 Series 2 Series 3

1962

1964

1966

1968

Time

Figura 4: Grco de uma srie temporal multivariada. a e Atravs do parmetro plot.type podemos indicar que pretendemos um s grco e a o a com todas as sries, e > m <- ts(matrix(rnorm(300), 100, 3), start = c(1961, 6), frequency = 12) > plot(m, plot.type = "single", col = 1:3) > legend("topright", legend = colnames(m), col = 1:3, lty = 1) o que leva ao grco na Figura 5. a

Series 1 Series 2 Series 3

m 3 2 1

1962

1964

1966 Time

1968

Figura 5: Grco unico de uma srie temporal multivariada. a e Existem uma srie de funes para manipular os objectos criados pela funao ts() e co c que podem ter grande utilidade. Vejamos alguns exemplos, > x <- ts(rnorm(10), frequency = 4, start = c(1959, 2)) > start(x) [1] 1959 > end(x) 2

Algumas funes co uteis

34

FUNDAMENTOS DA LINGUAGEM R

[1] 1961

> window(x, start = c(1959, 5)) 1960 1961 Qtr1 Qtr2 Qtr3 Qtr4 0.96364972 -1.42112904 -0.64183730 -0.24208549 1.39783879 0.24219084 -0.05084689

> window(x, end = c(1959, 7)) 1959 1960 Qtr2 Qtr3 0.9245848 -0.0970050 0.9636497 -1.4211290 -0.6418373 Qtr1 Qtr4 0.8055003

> window(x, start = c(1959, 4), end = c(1959, 9)) 1959 1960 1961 Qtr4 0.8055003 0.9636497 -1.4211290 -0.6418373 -0.2420855 1.3978388 Qtr1 Qtr2 Qtr3

Lags e diferenas c

A funo start() permite-nos obter a etiqueta temporal do in da srie, enquanto ca cio e que a funo end() faz o contrrio. Quanto ` funo window(), ela permite-nos extra ca a a ca r uma janela temporal da srie, explicitando o in e cio e o m dessa janela, ou omitindo um desses tempos o que faz com que seja assumido o in cio ou o nal de toda a srie, e respectivamente. > (x <- ts(rnorm(10), frequency = 4, start = c(1959, 2))) 1959 1960 1961 Qtr2 Qtr3 Qtr4 -0.53646433 -0.67589743 -0.43825372 0.60812619 0.26228902 -0.03652399 0.43490010 1.47686955 -1.24983261 1.44151984 Qtr1

> lag(x) Qtr1 Qtr2 Qtr3 1959 -0.53646433 -0.67589743 -0.43825372 1960 0.26228902 -0.03652399 0.43490010 1961 -1.24983261 1.44151984 > lag(x, 4) 1958 1959 1960 Qtr2 Qtr3 Qtr4 -0.53646433 -0.67589743 -0.43825372 0.60812619 0.26228902 -0.03652399 0.43490010 1.47686955 -1.24983261 1.44151984 Qtr1 Qtr4 0.60812619 1.47686955

> diff(x) 1959 1960 1961 Qtr3 -0.1394331 1.0463799 -0.3458372 -0.2988130 1.0419695 -2.7267022 2.6913525 Qtr1 Qtr2 Qtr4 0.2376437 0.4714241

> diff(x, differences = 2) Qtr1 1959 1960 1961 Qtr2 Qtr3 0.04702415 5.41805462 Qtr4 0.37707682 0.77023710

0.80873619 -1.39221706 0.57054536 -3.76867161

2.11

Sries Temporais e

35

> diff(x, lag = 2) Qtr1 1959 1960 1961 Qtr2 Qtr3 Qtr4 0.09821061 0.17261108

1.28402362 0.70054274 -0.64465017 1.51339354 -1.68473271 -0.03534971

A funo lag() permite-nos fazer um shift da srie para trs (por defeito) ou para a ca e a frente x unidades de tempo (o segundo argumento da funo). Quanto ` funo diff() ca a ca ela permite-nos calcular diferenas de vria ordem (parmetro dierences) entre valores c a a sucessivos, ou mesmo valores distanciados mais unidades de tempo (parmetro lag). a Por vezes estamos interessados em juntar vrias sries num s objecto, isto numa a e o e srie multivariada. A maior diculdade desta tarefa decorre da possibilidade de no e a haver total concordncia das etiquetas temporais das sries que pretendemos juntar. Ao a e utlizarmos objectos da classe ts o R vai encarregar-se de resolver este problema por ns! o Vejamos um exemplo: > (x <- ts(rnorm(10), frequency = 4, start = c(1959, 2))) 1959 1960 1961 Qtr2 1.01532292 0.28531497 0.45710867 0.03461353 -0.72061564 Qtr1 Qtr3 Qtr4 1.50409802 -0.59415289 0.28391136 0.16622712 0.08729295

Juntar sries numa e s o

> (y <- ts(rnorm(10), frequency = 4, start = c(1960, 1))) Qtr1 Qtr2 Qtr3 Qtr4 1960 -0.041664330 -0.058680340 -1.360239359 0.897174604 1961 0.008411543 0.279581887 -0.478224920 -0.370200800 1962 1.162627682 0.134785203 > cbind(x, y) 1959 1959 1959 1960 1960 1960 1960 1961 1961 1961 1961 1962 1962 x y Q2 1.01532292 NA Q3 1.50409802 NA Q4 -0.59415289 NA Q1 0.28531497 -0.041664330 Q2 0.45710867 -0.058680340 Q3 0.28391136 -1.360239359 Q4 0.16622712 0.897174604 Q1 0.03461353 0.008411543 Q2 -0.72061564 0.279581887 Q3 0.08729295 -0.478224920 Q4 NA -0.370200800 Q1 NA 1.162627682 Q2 NA 0.134785203

A funo cbind(), quando aplicada a sries temporais vai fazer uma juno delas ca e ca olhando para as respectivas etiquetas temporais e preenchendo os valores no concordana tes com NAs. A funo embed(), por sua vez, permite gerar diferentes colunas formadas pela srie ca e temporal deslizada diferentes passos temporais para trs. Vejamos um exemplo, a > (x <- ts(rnorm(10), frequency = 4, start = c(1959, 2))) 1959 1960 1961 Qtr2 Qtr3 Qtr4 -1.26304477 0.52757493 -1.66384494 1.79545393 0.07105220 -0.08895523 -1.77403572 0.82165185 0.14742042 1.33359531 Qtr1

Embeds temporais

36

FUNDAMENTOS DA LINGUAGEM R

> embed(x, 3) [,1] [,2] [,3] [1,] -1.66384494 0.52757493 -1.26304477 [2,] 1.79545393 -1.66384494 0.52757493 [3,] 0.07105220 1.79545393 -1.66384494 [4,] -0.08895523 0.07105220 1.79545393 [5,] -1.77403572 -0.08895523 0.07105220 [6,] 0.82165185 -1.77403572 -0.08895523 [7,] 0.14742042 0.82165185 -1.77403572 [8,] 1.33359531 0.14742042 0.82165185 Note, em primeiro lugar que o resultado uma matriz e no uma srie multivariada. e a e Na matriz resultante, a linha i tem os valores Yi+e1 , Yi+e2 , , Yi da srie temporal, e em que e o tamanho do embed indicado no segundo argumento da funo. e ca Um efeito semelhante, mas em que o resultado uma srie multivariada, pode ser e e obtido da seguinte forma, > x Qtr2 Qtr3 Qtr4 -1.26304477 0.52757493 -1.66384494 1.79545393 0.07105220 -0.08895523 -1.77403572 0.82165185 0.14742042 1.33359531 Qtr1

1959 1960 1961

> na.omit(cbind(lag(x, 2), lag(x), x)) lag(x, 2) lag(x) x Q2 -1.66384494 0.52757493 -1.26304477 Q3 1.79545393 -1.66384494 0.52757493 Q4 0.07105220 1.79545393 -1.66384494 Q1 -0.08895523 0.07105220 1.79545393 Q2 -1.77403572 -0.08895523 0.07105220 Q3 0.82165185 -1.77403572 -0.08895523 Q4 0.14742042 0.82165185 -1.77403572 Q1 1.33359531 0.14742042 0.82165185

1959 1959 1959 1960 1960 1960 1960 1961

Note como a funo na.omit() foi usada para retirar do resultado do cbind() as ca linhas em que existiam NAs. 2.11.2 Sries Irregulares e

Nas sries irregulares os valores no tm necessariamente que ser espalhados de forma e a e igual ao longo do tempo. Isto quer dizer que as etiquetas temporais no tm necesa e sariamente que ter um regularidade como acontece com as sries regulares que vimos e anteriormente. O R tem vrias packages que denem objectos espec a cos para armazenar este tipo de dados. A lista seguinte apresenta as principais:

A package its que dene os objectos its. A package tseries que dene os objectos irts. A package fBasics que dene os objectos timeSeries. A package zoo que dene os objectos zoo.

Criar uma srie e irregular

No nosso estudo vamos usar a package zoo. Vejamos como criar um objecto zoo em R:

2.11

Sries Temporais e

37

> library(zoo) > (x <- zoo(rnorm(5), c("2006-3-21", "2006-3-24", "2006-6-21", + "2006-6-23", "2006-09-21"))) 2006-09-21 2006-3-21 -2.45827056 -1.13546300 > index(x) [1] "2006-09-21" "2006-3-21" > coredata(x) [1] -2.45827056 -1.13546300 0.10284559 -0.57846242 -0.04002960 "2006-3-24" "2006-6-21" "2006-6-23" 2006-3-24 2006-6-21 2006-6-23 0.10284559 -0.57846242 -0.04002960

O segundo argumento da funo zoo(), as etiquetas temporais dos dados, pode ser ca de qualquer tipo (!), desde que faa sentido ordenar os seus valores (isto desde que se c e possa aplicar a funo order() aos valores). Fora isto, no h qualquer limitao o que ca a a ca torna este tipo de objectos bastante ex veis. A maior parte das vezes as etiquetas das nossas sries temporais vo ser datas/horas. e a Nesse contexto, vamos agora ver maneiras alternativas de lidar com datas e/ou horas em R. O R tem vrios tipos de objectos para lidar com datas e tempo em geral. Vejamos a alguns exemplos: 1. Os objectos do tipo Date Neste tipo de objectos as datas so representadas internamente como o nmero de a u dias que passaram desde 1970-01-01. > Sys.Date() [1] "2006-10-21" > hoje <- Sys.Date() > format(hoje, "%d %b %Y") [1] "21 Out 2006" > (dezsemanas <- seq(hoje, len = 10, by = "1 week")) [1] "2006-10-21" "2006-10-28" "2006-11-04" "2006-11-11" "2006-11-18" [6] "2006-11-25" "2006-12-02" "2006-12-09" "2006-12-16" "2006-12-23" > weekdays(hoje) [1] "sbado" a > months(hoje) [1] "Outubro" A funo Sys.Date() permite-nos obter a data de hoje num objecto do tipo Date. ca A funo format() permite mostrar um objecto deste tipo de muitas formas, atraca vs de um segundo parmetro que tem inmeras possibilidades para extra e mose a u r trar partes de uma data no cran. Consulte a ajuda desta funo para saber mais e ca sobre estas variantes. A funo seq(), que j estudamos anteriormente, quando ca a aplicada a objectos do tipo Date permite gerar sequncias de datas. A funo e ca possui valores prprios no parmetro by que podem ser usados para produzir a o a sequncia desejada8 . A funo weekdays() permite-nos obter o dia da semana core ca respondente ` data em causa, enquanto que a funo months() faz o mesmo para a ca o nome do ms. e
8 Consulte

Datas/horas em R

Objectos do tipo Date

a ajuda da funo seq.Date para obter mais alternativas. ca

38

FUNDAMENTOS DA LINGUAGEM R

> as.Date("2006-9-23") - as.Date("2003-04-30") Time difference of 1242 days > ISOdate(2001, 1, 1) - ISOdate(2000, 6, 14) Time difference of 201 days > cut(ISOdate(2001, 1, 1) + 70 * 86400 * runif(10), "weeks") [1] 2001-02-12 2001-01-15 2001-01-29 2001-01-29 2001-01-08 2001-02-26 [7] 2001-01-29 2001-01-01 2001-01-08 2001-01-01 9 Levels: 2001-01-01 2001-01-08 2001-01-15 2001-01-22 ... 2001-02-26 > table(cut(seq(ISOdate(2006, 1, 1), to = ISOdate(2006, 12, 31), + by = "day"), "month")) 2006-01-01 2006-02-01 2006-03-01 2006-04-01 2006-05-01 2006-06-01 2006-07-01 31 28 31 30 31 30 31 2006-08-01 2006-09-01 2006-10-01 2006-11-01 2006-12-01 31 30 31 30 31 Nestes novos exemplos vemos a funo as.Date(), que permite converter uma ca string para um objecto do tipo Date. Vemos tambm a funo ISOdate() que e ca nos possibilita uma forma alternativa de criar um objecto do tipo Date indicando o ano, ms e dia pelos seus nmeros. Vemos ainda a possibilidade que o R nos d de e u a usar alguns operadores aritmticos com objectos do tipo Date, obtendo resultados e em termos da diferena temporal entre as datas. Por m, vemos dois exemplos de c utilizao da funo cut() que, quando aplicada a objectos do tipo Date, gera um ca ca factor em que cada valor resulta de uma discretizao das datas fornecidas no prica meiro argumento do cut(), para um conjunto de intervalos denidos pelo segundo argumento. No primeiro exemplo os intervalos so denidos dividindo as datas por a semanas, enquanto que no segundo por ms. No segundo exemplo, vemos uma e e utilidade deste tipo de discretizao, aplicando a funo table() ao factor resulca ca tante, obtendo deste modo uma contagem do nmero de datas em cada intervalo u (cada ms neste exemplo). Na realidade, neste segundo exemplo, se repararmos e atentamente nas datas que so fornecidas ao cut(), o que vamos obter o nmero a e u de dias em cada ms do ano de 2006. e
Objectos do tipo POSIXt

2. Objectos do tipo POSIXt Este tipo de objectos permite guardar tempos que contm informao no s sobre e ca a o a data, como os anteriores, mas tambm sobre as horas. Com este tipo de objectos e podemos guardar tempos at ao segundo. Na realidade existem dois tipos de sube objectos: (a) POSIXct que representam as datas como o nmero de segundos que passaram u desde 1970. (b) POSIXlt que representam as datas como uma lista com vrias componentes, a como: sec; min; hour; mday; mon; year; etc. Vejamos exemplos destes tipo de objectos: > (z <- Sys.time()) [1] "2006-10-21 00:59:09 Hora de Ver~o de GMT" a > as.POSIXlt(Sys.time(), "GMT") [1] "2006-10-20 23:59:09 GMT"

2.11

Sries Temporais e

39

> as.POSIXct("2006-12-23 12:45") - as.POSIXct("2006-12-21 21:54") Time difference of 1.61875 days > format(Sys.time(), "%a %b %d %X %Y %Z") [1] "sb Out 21 0:59:09 2006 Hora de Ver~o de GMT" a a A funo Sys.time() obtm a data/hora actual no computador num objecto do ca e tipo POSIXt. A funo as.POSIXlt() pode ser usada para converter diferentes ca objectos para a classe POSIXlt, e neste caso aproveitamos tambm para mostrar e como, durante essa converso, resolvemos mudar de fuso horrio, do nosso para a a GMT. Vemos tambm um exemplo de como fazer aritmtica com este tipo de e e objectos, alm de um outro exemplo do uso da funo format() que j vimos e ca a acima. > x <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960") > strptime(x, "%d%b%Y") [1] "1960-01-01" "1960-01-02" "1960-03-31" "1960-07-30" > > > > dates <- c("02/27/92", "02/27/92", "01/14/92", "02/28/92", "02/01/92") times <- c("23:03:20", "22:29:56", "01:03:30", "18:21:03", "16:56:26") x <- paste(dates, times) strptime(x, "%m/%d/%y %H:%M:%S")

[1] "1992-02-27 23:03:20" "1992-02-27 22:29:56" "1992-01-14 01:03:30" [4] "1992-02-28 18:21:03" "1992-02-01 16:56:26" Nestes novos exemplos vemos ilustraes de uma operao bastante frequente, em co ca particular se vamos importar dados que involvem datas, de outras aplicaes. Norco malmente recebemos essas datas como strings, e portanto temos depois que extra r dessas strings as nossas datas/horas. O problema que no existe uma unica e a norma seguida por todos para representar datas. Aqui entra a funo strptime() ca que pode ser usada para extra datas/horas de strings indicando quar o formato r em que essas datas/horas esto representadas nas strings. Isso feito atravs do a e e segundo argumento da funo que usa um conjunto de cdigos com vrio signica o a cado, muito ao estilo do que vimos na funo format(). Para mais detalhes sobre ca estes cdigos o melhor consultar a ajuda da funo. o e ca Aps esta incurso pelas datas e horas em R voltemos aos nossos objectos zoo. o a Comeemos por ver exemplos de visualizao deste tipo de objectos. Os grcos da c ca a e e Figura 6 mostram-nos uma srie univariada e tambm uma multivariada, guardadas em objectos zoo. > + > + > > > > > z <- zoo(rnorm(100), sort(ISOdate(2001, runif(100))) z.mtx <- zoo(matrix(rnorm(100), 50, 2), 1) + 70 * 86400 * runif(50))) par(mfrow = c(1, 2)) plot(z) plot(z.mtx, plot.type = "single", col = legend("topright", c("1col", "2col"), par(mfrow = c(1, 1)) 1, 1) + 70 * 86400 * sort(ISOdate(2001, 1,

Sries multivariadas e irregulares

1:2) lty = 1, col = 1:2)

Vejamos agora um conjunto de funes uteis para diversos tipos de manipulao de co ca objectos zoo.

In cio e m de sries e zoo

40

FUNDAMENTOS DA LINGUAGEM R

z.mtx

9.79e+08

9.83e+08 Index

1col 2col

9.79e+08

9.83e+08 Index

Figura 6: Grcos de objectos zoo. a

2.11

Sries Temporais e

41

> (x <- zoo(rnorm(15), seq(as.Date("2006-09-01"), length = 15, + by = "days"))) 2006-09-01 0.367653423 2006-09-07 0.209334800 2006-09-13 -0.172072092 > start(x) [1] "2006-09-01" > end(x) [1] "2006-09-15" > x[3:6] 2006-09-03 1.342642534 2006-09-04 2006-09-05 2006-09-06 2.005092105 -0.310355469 -0.001024538 2006-09-02 2006-09-03 2006-09-04 2006-09-05 2006-09-06 1.446087183 1.342642534 2.005092105 -0.310355469 -0.001024538 2006-09-08 2006-09-09 2006-09-10 2006-09-11 2006-09-12 1.250436925 0.161235127 -0.270383756 2.978076138 -1.512003802 2006-09-14 2006-09-15 0.237434668 -1.095001597

> x[coredata(x) > 0] 2006-09-01 2006-09-02 2006-09-03 2006-09-04 2006-09-07 2006-09-08 2006-09-09 0.3676534 1.4460872 1.3426425 2.0050921 0.2093348 1.2504369 0.1612351 2006-09-11 2006-09-14 2.9780761 0.2374347 As funes start() e end() funcionam da mesma forma do que com objectos ts. co COmo vemos a indexao funciona da mesma forma como se de um vector normal ca se trata-se, mantendo-se as respectivas etiquetas temporais. De qualquer modo convm e no esquecer que se trata, no de um vector normal, mas de um objecto mais complexo a a que contm para alm dos valores da srie, as etiquetas. E importante lembrar-mo-nos e e e disso quando pretendemos escolher um subconjunto de valores de uma srie impondo e uma condio aos seus valores, como ilustrado no ultimo exemplo. Nesses casos temos ca e que nos lembrar que a condio a ser imposta sobre os valores (e da o uso da funo ca e ca coredata()) e no sobre o objecto como um todo. a > x[as.Date("2006-09-14")] 2006-09-14 0.2374347 > window(x, start = as.Date("2006-09-10"), end = as.Date("2006-09-15")) 2006-09-10 2006-09-11 2006-09-12 2006-09-13 2006-09-14 2006-09-15 -0.2703838 2.9780761 -1.5120038 -0.1720721 0.2374347 -1.0950016 > (y <- zoo(rnorm(10), seq(as.Date("2006-09-10"), length = 10, + by = "days"))) 2006-09-10 0.67339402 2006-09-16 1.27971776 > x - y 2006-09-11 2006-09-12 2006-09-13 1.75291084 -0.13133473 -0.01916885 2006-09-17 2006-09-18 2006-09-19 0.79160867 0.64387366 -0.64057581 2006-09-14 2006-09-15 0.50119663 -1.07051968

42

FUNDAMENTOS DA LINGUAGEM R

2006-09-10 -0.94377777

2006-09-11 2006-09-12 2006-09-13 2006-09-14 2006-09-15 1.22516530 -1.38066907 -0.15290324 -0.26376196 -0.02448191
Janelas temporais de objectos zoo

No primeiro exemplo vemos como podemos indexar um objecto zoo por valores das etiquetas temporais. No segundo vemos a funo window() aplicada a um objecto ca zoo. Em seguida vemos outros exemplos envolvendo sequncias de datas e operaes e co aritmticas com objectos com etiquetas temporais no totalmente coincidentes. e a Nos exemplos seguintes vemos como juntar sries zoo. e > x <- zoo(rnorm(7), seq(as.Date("2006-09-01"), length = 7, by = "days")) > y <- zoo(rnorm(7), seq(as.Date("2006-09-06"), length = 7, by = "days")) > cbind(x, y) x y 2006-09-01 0.072992109 NA 2006-09-02 -0.302664430 NA 2006-09-03 0.597683194 NA 2006-09-04 0.572150915 NA 2006-09-05 -0.002487241 NA 2006-09-06 -0.898433693 -0.9438510 2006-09-07 0.753787841 1.3302728 2006-09-08 NA 1.1581772 2006-09-09 NA -0.4568366 2006-09-10 NA -0.7295473 2006-09-11 NA -0.6993896 2006-09-12 NA -0.6021335 > merge(x, y, all = FALSE) x y 2006-09-06 -0.8984337 -0.943851 2006-09-07 0.7537878 1.330273
Juntar objectos zoo

A funo cbind() pode ser usada para juntar duas sries univariadas numa srie ca e e multivariada, encarregando-se o R de tratar de valores com etiquetas no concordantes a (os valores da outra srie cam com NA), enquanto que a juno usando a funo merge() e ca ca permite, em alternativa e atravs do parmetro all, indicar que s queremos na juno e a o ca os valores concordantes. > xx <- x[1:6] > lag(xx) 2006-09-01 -0.302664430 2006-09-02 0.597683194 2006-09-03 2006-09-04 2006-09-05 0.572150915 -0.002487241 -0.898433693

> merge(xx, lag(xx)) xx lag(xx) 2006-09-01 0.072992109 -0.302664430 2006-09-02 -0.302664430 0.597683194 2006-09-03 0.597683194 0.572150915 2006-09-04 0.572150915 -0.002487241 2006-09-05 -0.002487241 -0.898433693 2006-09-06 -0.898433693 NA > diff(xx) 2006-09-02 -0.37565654 2006-09-03 2006-09-04 2006-09-05 2006-09-06 0.90034762 -0.02553228 -0.57463816 -0.89594645

2.11

Sries Temporais e

43

nes, diferenas co c

ags de objectos

oo

No cdigo anterior vemos a utilizao da funo lag() sobre objectos zoo, bem o ca ca como mais um exemplo de juno de sries atravs da funo merge(). J a funo ca e e ca a ca diff() permite-nos obter diferenas entre valores sucessivos da srie. c e Vejamos agora alguns exemplos de formas de lidar com valores desconhecidos em sries temporais guardadas em objectos zoo. e > x 2006-09-01 2006-09-02 0.072992109 -0.302664430 2006-09-07 0.753787841 2006-09-03 0.597683194

Valores desconhecidos em objectos zoo

2006-09-04 2006-09-05 2006-09-06 0.572150915 -0.002487241 -0.898433693

> x[sample(1:length(x), 3)] <- NA > x 2006-09-01 2006-09-02 2006-09-03 2006-09-04 2006-09-05 2006-09-06 2006-09-07 NA -0.3026644 NA 0.5721509 NA -0.8984337 0.7537878 > na.omit(x) 2006-09-02 2006-09-04 2006-09-06 2006-09-07 -0.3026644 0.5721509 -0.8984337 0.7537878 > na.contiguous(x) 2006-09-06 2006-09-07 -0.8984337 0.7537878 > na.approx(x) 2006-09-02 2006-09-03 2006-09-04 2006-09-05 2006-09-06 2006-09-07 -0.3026644 0.1347432 0.5721509 -0.1631414 -0.8984337 0.7537878 > na.locf(x) 2006-09-02 2006-09-03 2006-09-04 2006-09-05 2006-09-06 2006-09-07 -0.3026644 -0.3026644 0.5721509 0.5721509 -0.8984337 0.7537878 A funo na.omit() permite eliminar os pontos em que o valor NA. A funo ca e ca na.contiguous() extrai a mais longa sequncia sem valores NA. A funo na.approx() e ca usa interpolao linear para preencher os valores NA, enquanto que a funo na.locf() ca ca preenche cada valor NA com o valor no desconhecido mais recente (i.e. anterior ao NA). a Por vezes temos interesse em aplicar uma qualquer funo a uma janela de tamanho x ca da nossa srie. Ainda mais interessante fazer essa janela deslizar pela srie toda. Para e e e isso podemos usar as seguintes funes: co > (x <- zoo(rnorm(7), seq(as.Date("2006-09-01"), length = 7, by = "days"))) 2006-09-01 -0.961754723 2006-09-07 -1.376853779 2006-09-02 2006-09-03 0.008705073 -0.991048555 2006-09-04 1.438521921 2006-09-05 0.650619612 2006-09-06 0.312436234

Funes deslizantes co

> rapply(x, 4, mean) 2006-09-02 2006-09-03 2006-09-04 2006-09-05 -0.1263941 0.2766995 0.3526323 0.2561810 > rapply(x, 4, mean, align = "right")

44

FUNDAMENTOS DA LINGUAGEM R

2006-09-04 2006-09-05 2006-09-06 2006-09-07 -0.1263941 0.2766995 0.3526323 0.2561810 > rollmean(x, 3) 2006-09-02 2006-09-03 2006-09-04 2006-09-05 2006-09-06 -0.6480327 0.1520595 0.3660310 0.8005259 -0.1379326 > rollmean(x, 3, na.pad = T) 2006-09-01 2006-09-02 2006-09-03 2006-09-04 2006-09-05 2006-09-06 2006-09-07 NA -0.6480327 0.1520595 0.3660310 0.8005259 -0.1379326 NA > rollmean(x, 3, na.pad = T, align = "right") 2006-09-01 2006-09-02 2006-09-03 2006-09-04 2006-09-05 2006-09-06 2006-09-07 NA NA -0.6480327 0.1520595 0.3660310 0.8005259 -0.1379326 > rollmean(x, 3, align = "right") 2006-09-03 2006-09-04 2006-09-05 2006-09-06 2006-09-07 -0.6480327 0.1520595 0.3660310 0.8005259 -0.1379326 A funo rapply() permite-nos aplicar uma funo qualquer a uma janela deslizante ca ca de um certo tamanho (2 argumento), de uma srie zoo. A aplicao da funo pode e ca ca ser feita centrando a janela em cada ponto (valor por defeito), ou alinhando a janela ` direita ou ` esquerda, usando para isso o parmetro align. A funo rollmean() a a a ca no mais do que um envelope ` chamada da funo rapply() com a funo mean. a e a ca ca Ambas as funes (rapply e rollmean) tm um parmetro na.pad que permite indicar se co e a pretendemos que as etiquetas temporais para as quais no poss calcular o valor da a e vel funo, por inexistncia de valores sucientes para preencher a janela deslizante, devero ca a a ou no ser preenchidos por NAs. a

45

3
3.1

Programao em R ca
Interaco com o Utilizador ca

O R possui diversas funes que tm como objectivo ou escrever contedos no cran, ou co e u e ler coisas introduzidas pelo utilizador no teclado, isto para gerir a interaco com o e ca utilizador. A funo print(), por exemplo, pode ser usada para escrever o contedo de qualquer ca u objecto9 . Por vezes, quando os objectos so muito grandes (p. ex. grandes listas) mais a e conveniente usar a funo str(), ca > str(list(nros = rnorm(100), dados = matrix(rnorm(10000), 100, + 100))) List of 2 $ nros : num [1:100] -0.543 0.654 $ dados: num [1:100, 1:100] -2.210 0.207 0.511 0.454 -1.125 ... 1.681 0.358 0.656 ...

Escrever no cran e

A funo cat() tambm pode ser usada para escrever objectos ou constantes. Funca e ciona com um nmero qualquer de argumentos, e o que faz transformar os seus arguu e mentos em strings, concaten-los, e s depois os escreve no cran, a o e > x <- 34 > cat("x tem o valor de ", x, "\t o que estranho!\n") e x tem o valor de 34 o que estranho! e

Nesta instruo, certos caracteres contidos em strings tm signicado especial. Por ca e exemplo \t signica o caracter Tab, enquanto \n signica o caracter Newline (isto , e muda de linha). Relativamente a leitura de dados introduzidos pelo utilizador tambm existem vrias e a hipteses em R. A funo scan(), por exemplo, permite ler dados de vrio tipo, o ca a > x <- scan(n=5) 1: 45 21.4 56 66.54 45.8787 Read 5 items > x [1] 45.0000 21.4000 56.0000 66.5400 45.8787 Ainda um outro exemplo, > x <- scan() 1: 45 66 34.2 4: 456.7 7 6: 12.2 7: Read 6 items > x [1] 45.0 66.0

Leitura de dados

34.2 456.7

7.0

12.2

E nalmente um outro exemplo com dados de outro tipo, > scan(what=character()) 1: 'erer' 'fdf' 3: '233' 44.5 5: Read 4 items [1] "erer" "fdf" "233" "44.5" A funo tem ainda muitas outras poss ca veis formas de ser usada que podem ser consultadas na respectiva ajuda.
9 Note que este mais um exemplo de uma funo genrica (c.f. Seco 3.4), existindo diversos mtodos e ca e ca e para diferentes classes de objectos.

46

PROGRAMACAO EM R

3.2

Estruturas de Controlo da Linguagem R

A linguagem R, como a qualquer linguagem de programao, possui vrias instrues ca a co destinadas a alterar o curso sequencial normal de execuo dos programas. ca 3.2.1 Instrues Condicionais co

A instruo if ca

As instrues condicionais permitem ao programador explicitar diferentes alternativas a co serem executadas dependendo de alguma condio a ser testada na altura da execuo ca ca das instrues. co A instruo if, por exemplo, permite explicitar uma condio booleana e dois conca ca juntos de instrues alternativos que so executados dependendo do valor da condio. co a ca Vejamos um pequeno exemplo, > if (x > 0) y <- z / x else y <- z Esta instruo pode ser facilmente explicada dizendo que no caso de a varivel x ser ca a superior a 0, a instruo que executada a atribuio da expresso z/x a y. Caso ca e e ca a contrrio, o R efectua a outra atribuio que vem ` frente da palavra else. Em termos a ca a genricos, a semntica associada ` instruo if pode ser descrita da seguinte forma: se e a a ca a condio booleana inclu entre parenteses ` frente da palavra if fr verdadeira, o R ca da a o executa o conjunto de instruoes que aparecem entre esta condio e a palavra else; se a c ca condio fr falsa, executado o conjunto de instrues que aparece ` frente da palavra ca o e co a else. No sentido de passarmos do exemplo apresentado acima, para um exemplo mais genrico envolvendo um conjunto de instrues, temos que introduzir a noo de conjunto e co ca ou bloco de instrues na linguagem R. Em R um bloco de instrues normalmente co co e indicado fornecendo essas instrues em linhas separadas e seguidas, delimitadas por co chavetas. Por exemplo, > if (x > 0) { cat('x positivo.\n') e y <- z / x } else { cat('x n~o positivo!\n') a e y <- z } Note-se que neste pequeno exemplo usamos a identao das instrues em cada um ca co dos 2 blocos de instrues contidos na instruo if. Embora no obrigatria, esta co ca a o forma de proceder sempre aconselhvel, por facilitar a leitura da instruo. e a ca A instruo if tem ainda outras variantes que passamos a descrever. Por exemplo, ca a clasula else opcional, podendo ns usar ifs sem alternativa para o caso de a u e o condio ser falsa. Nesse caso, o R no far nada como resultado da instruo if. ca a a ca Podemos ainda usar vrias instrues if aninhadas, como no exemplo seguinte: a co > if (idade < 18) { grupo <- 1 } else if (idade < 35) { grupo <- 2 } else if (idade < 65) { grupo <- 3 } else { grupo <- 4 } Note-se que embora s exista uma instruo em cada bloco deste exemplo, colocamos o ca todas as instrues entre chavetas como se tratassem de conjuntos de instrues. Neste co co exemplo concreto, no colocar as chavetas iria originar um erro de sintaxe. A explicao a ca

Blocos de instrues co

IFs aninhados

3.2

Estruturas de Controlo da Linguagem R

47

de tal comportamento, aparentemente estranho, tem a ver com o facto de o R ser uma linguagem interpretada e sai um pouco do mbito desta disciplina. De qualquer modo, a uma boa regra para evitar problemas, usar sempre as chavetas para delimitar as duas e partes de uma instruo if. Mais detalhes e explicaes sobre este comportamento podem ca co ser obtidas na seco 3.2.1 do manual R Language Denition que vem com o R e est ca a dispon no sistema de ajuda do R. vel Uma funo relacionada com a instruo if a funo ifelse(). Esta funo perca ca e ca ca mite trabalhar com vectores de condioes boleanas. O seu signicado poder ser melhor c a apreendido vom um pequeno exemplo, > x <- rnorm(5, sd = 10) > x [1] -5.9357417 -4.5964847 0.5452268 -2.9091063 -9.2760717

A funo ifelse() ca

> sig <- ifelse(x < 0, "-", "+") > sig [1] "-" "-" "+" "-" "-" A instruo switch() pode tambm ser usada para escolher uma de vrias alternaca e a tivas. Ela consiste numa srie de argumentos em que dependendo do valor do primeiro e argumento, o resultado do switch um dos outros argumentos. Vejamos em primeiro e lugar um exemplo em que o primeiro argumento um nmero. Neste caso, o valor desse e u nmero determina qual o argumento do switch que avaliado. Por exemplo, u e > op <- 2 > vs <- rnorm(10) > switch(op, mean(vs), median(vs)) [1] -0.1936888 O valor obtido resulta de aplicar a funo median() ao vector vs, uma vez que o ca valor de op 2, e logo escolhido o segundo argumento a seguir ao teste contido no e e primeiro argumento do switch. Na realidade, todos os argumentos a seguir ao primeiro so tomados como uma lista (c.f. Seco 2.9) que pode ter nomes associados a cada a ca componente como vamos ver no exemplo a seguir. No caso de no ter nomes, como a no exemplo acima, escolhida a componente da lista pelo nmero indicado no primeiro e u argumento do switch. No caso de o nmero ser superior ao tamanho da lista, o resultado u do switch NULL. e Ao dar nomes `s componentes da lista, passamos a poder usar valores textuais no a primeiro argumento, como podemos ver no exemplo seguinte, > semaforo <- "verde" > switch(semaforo, verde = "continua", amarelo = "acelera", vermelho = "pra") a [1] "continua" Por estes exemplos podemos ver que a instruo switch tem a forma genrica de ca e switch(valor,lista) e que o resultado da instruo no mais do que usar o contedo do primeiro argumento ca a e u para aceder a uma das componentes da lista cujo contedo das componentes indicado u e nos argumentos seguintes da instruo. Se o primeiro argumento fr um nmero ento ca o u a o resultado a componente com esse nmero de ordem, se o primeiro argumento fr um e u o nome, ento extra a componente com esse nome. a e da
A funo switch() ca

48

PROGRAMACAO EM R

3.2.2

Instrues Iterativas co

O R tem vrias instrues iterativas (ciclos) que nos permitem repetir blocos de instrua co ces. Para alm destas instrues o R possui ainda duas instrues que podem ser usadas o e co co para controlar a execuo dos ciclos. ca A instruo while tem a seguinte estrutura genrica, ca e while (<condi~o boolena>) ca <bloco de instru~es> co A sua semntica pode ser descrita por: enquanto a condio booleana fr verdadeira, a ca o repetir o bloco de instrues no corpo do ciclo. Vejamos um pequeno exemplo, co > > + + + > x <- rnorm(1) while (x < -0.3) { cat("x=", x, "\t") x <- rnorm(1) } x

Instrues iterativ co

O ciclo while

[1] 1.516122 Note-se que as instrues no bloco dentro do ciclo podem nunca ser executadas, co bastando para isso que a condio seja falsa da primeira vez que o R chega ao ciclo. ca No exemplo acima, se o primeiro nmero sorteado pela funo rnorm() fr superior ou u ca o igual a -0.3, as instrues do ciclo no so executadas nenhuma vez. Em sintese podemos co a a dizer que as instrues no bloco do ciclo while podem ser executadas zero ou mais vezes. co Atente-se que um erro relativamente frequente escrever blocos de instrues que e co levam a que os ciclos nunca mais terminem. Por exemplo, se no exemplo anterior nos tivessemos enganado e, dentro do ciclo, tivessemos escrito y <- rnorm(1), em vez da atribuio que a se encontra, caso o R entrasse no ciclo, nunca mais o terminaria10 . ca Como regra geral podemos dizer que se deve escrever os ciclos de tal forma que exista sempre possibilidade de que a(s) varivel(eis) que controla(m) a execuo dos mesmos a ca (no nosso exemplo a varivel x), possa sempre ver o seu valor alterado nas instrues que a co formam o bloco contido no ciclo, de forma a que a condio possa vir a ser falsa, ou seja ca de forma a que o ciclo possa vir a terminar. A instruo repeat permite mandar o R executar um bloco de instrues uma ou ca co mais vezes. A sua forma genrica , e e repeat <bloco de instru~es> co Repare que uma vez que no existe qualquer condio lgica a governar a execuo a ca o ca repetida do bloco de instruoes, como no caso do ciclo while, o R socorre-se de outras c instrues que permitem parar a execuo de um processo iterativo. Em concreto a co ca instruo break se executada dentro do ciclo faz o R terminar a repetio da execuo ca ca ca do bloco de instrues. Mais uma vez, para evitar ciclos innitos convir garantir que co a tal instrues pass de ser executada no bloco de instrues que forma o corpo do co e vel co ciclo. Vejamos um pequeno exemplo que l frases introduzidas pelo utilizador at este e e introduzir uma frase vazia, texto <- c() repeat { cat('Introduza uma frase ? (frase vazia termina) ') fr <- readLines(n=1) if (fr == '') break else texto <- c(texto,fr) }
10 Se por acaso isso lhe acontecer, pode pressionar a tecla Esc para fazer o R abortar a computao do ca ciclo.

O ciclo repeat

Sa de um r bloco/ciclo

3.2

Estruturas de Controlo da Linguagem R

49

Conforme dever ser bvio, este ciclo s ir terminar quando a varivel fr, que contm a o o a a e a frase que o utilizador acabou de introduzir, fr vazia. Se tal no acontecer, a instruo o a ca break no executada e como tal o ciclo repetido, ou seja nova frase pedida. a e e e O prximo exemplo ilustra o uso de outra instruo que pode ser usada para controlar o ca o que feito num ciclo, a instruo next, e ca repeat { cat('Introduza um nro positivo ? (zero termina) ') nro <- scan(n=1) if (nro < 0) next if (nro == 0) break pos <- c(pos,nro) } Neste exemplo pretende-se ler um conjunto de nmeros positivos que so coleccionados u a num vector. O utilizador dever introduzir o nmero zero para terminar o ciclo. No caso a u de o utilizador introduzir um nmero negativo, pretende-se pedir novo nmero sem que u u o nmero negativo seja acrescentado ao vector com os nmeros lidos. Conseguimos esse u u efeito com a instruo next. Quando o R encontra esta instruo, salta imediatamente ca ca para o in do ciclo que esteja a executar, no executando portanto qualquer instruo cio a ca que viesse a seguir ao next dentro do ciclo. Finalmente o R tem ainda a instruo for que permite controlar o nmero de vezes ca u que um ciclo executado atravs de uma varivel de controlo que vai tomar uma srie e e a e de valores pr-denidos em cada iteraao do ciclo. A sua sintaxe genrica , e c e e for(<var> in <conjunto>) <bloco de instru~es> co Vejamos um pequeno exemplo de utilizao destes ciclos, ca > > > + + + + + x <- rnorm(10) k <- 0 for (v in x) { if (v > 0) y <- v else y <- 0 k <- k + y }

Avanar para a c prxima iterao o ca

O ciclo for

Este pequeno ciclo comea por obter 10 nmero aleatrios de uma distribuio normal, c u o ca e depois obtm a soma daqueles que so positivos. Para isso usado um ciclo for em e a e que a varivel de controlo, neste caso chamada v, vai tomar, em cada iterao, um dos a ca valores do conjunto x, isto os 10 nmeros sorteados. Isto quer dizer que na primeira e u iterao o valor de v igual a x[1], na segunda igual a x[2] e assim sucessivamente ca e e para todos os elementos de x. Note que este um simples exemplo ilustrativo do uso do e for, uma vez que em termos de estilo de programao ` R a soluo para este problema ca a ca poderia ser obtida de forma muito mais simples, sem recurso a qualquer ciclo, > k <- sum(x[x > 0]) Note-se ainda que esta segunda forma seria muito mais eciente em termos de tempo de execuo, embora para um vector com este tamanho a diferena seja irrelevante. ca c O mesmo j no se poder dizer para vectores maiores como se pode constatar nesta a a a pequena experincia, e > x <- rnorm(1e+05) > t <- Sys.time() > k <- 0
Ecincia dos ciclos e

50

PROGRAMACAO EM R

> for (v in x) { + if (v > 0) + y <- v + else y <- 0 + k <- k + y + } > Sys.time() - t Time difference of 3.188 secs > t <- Sys.time() > k <- sum(x[x > 0]) > Sys.time() - t Time difference of 0.07799983 secs
Tempos de execuo ca

A funo Sys.time() permite-nos aceder ao relgio do computador, conseguindo ca o dessa forma temporizar a execuo de uma parte do nosso cdigo como vemos no exemplo. ca o O que tambm podemos ver a diferena muito signicativa dos tempos de execuo e e c ca envolvendo o ciclo for e sem esse ciclo. Ou seja para obter o mesmo resultado demoramos cerca de 30 vezes mais! De facto, uma lio a aprender deste pequeno exemplo que os ca e ciclos so estruturas computacionalmente pesadas na linguagem R 11 e que muitas vezes a os podemos evitar usando a vectorizao das operaes que o R disponibiliza. ca co 3.2.3 Evitando ciclos

Mtodos para evitar e ciclos

O R possui, como a maioria das linguagens, objectos que permitem armazenar conjuntos de valores (p. ex. vectores, matrizes, etc.). Existem inmeros problemas onde para os u resolver, precisamos de percorrer todos os elementos desses objectos. Na maioria das linguagens isso faz-se com o recurso a ciclos. No R, temos felizmentes vrias alternativas a bastante mais prticas e sintticas, para alm de muito mais ecientes como vimos no a e e ultimo exemplo da seco anterior. ca Uma das formas mais comuns de evitar os ciclos consiste em tirar partido do facto de muitas funes do R serem vectorizveis. Por exemplo, se pretendemos sumar todos co a os elementos de uma matriz m em vez de andarmos a percorr-los, usando para isso e dois ciclos for aninhados um dentro do outro (para permitir percorrer todas as colunas, para cada linha), como comum em muitas lingaugens de programao, em R podemos e ca simplesmente fazer s <- sum(m). Compare a simplicidade disto com a verso dos ciclos, a > m <- matrix(rnorm(10), 5, 2) > s <- 0 > for (c in 1:ncol(m)) for (l in 1:nrow(m)) s <- s + m[l, c] Para alm da maior simplicidade nunca demais realar que a verso com ciclos dee e c a morar consideravelmente mais tempo a ser executada, o que pode ser critico em matrizes muito grandes. O R tem ainda outras funes que podem ser explicitamente usadas para vectorizar co operaes. Suponhamos que pretendemos saber o valor m co nimo de cada coluna de uma matriz. No fundo o que pretendemos aplicar a funo min() a cada uma das colunas da e ca matriz. Em R podemos implementar essa ideia atravs da funo apply(), como vemos e ca em seguida, > m <- matrix(rnorm(100), 10, 10) > apply(m, 2, min) [1] -0.2740504 -1.4357644 -2.3413347 -1.7631999 -1.8275833 -1.5714361 [7] -1.3689081 -0.9579934 -2.9972401 -0.4734547
11 Note-se

A funo apply ca

no entanto que isto tem vindo a melhorar de forma signicativa nas verses mais recentes. o

3.2

Estruturas de Controlo da Linguagem R

51

A funo apply() permite-nos aplicar uma qualquer funo a uma das dimenses ca ca o de uma matriz ou array. Neste caso estamos a aplicar a funo min() ` 2 dimenso ca a a (as colunas) da matriz m. O resultado um vector de nmeros, os m e u nimos de cada coluna. Se pretendessemos o mesmo resultado sobre as linhas bastaria colocar um 1 no segundo argumento da funo, indicando desta forma que a funo deveria ser aplicada ca ca a ` 1 dimenso do objecto.12 a A funoo tapply() permite executar operaes semelhantes mas em sub-grupos dos ca co dados, determinados por valores de factores. Vejamos um exemplo usando um conjunto de dados que vem com o R para efeitos ilustrativos, > data(warpbreaks) > head(warpbreaks) 1 2 3 4 5 6 breaks wool tension 26 A L 30 A L 54 A L 25 A L 70 A L 52 A L

A funo tapply ca

> tapply(warpbreaks$breaks, warpbreaks[, -1], sum) tension wool L M H A 401 216 221 B 254 259 169 Como vemos o conjunto de dados warpbreaks possui 2 colunas que so factores a (wool e tension). A chamada ` funo tapply() calcula a soma da coluna breaks a ca deste conjunto de dados, mas para todos os sub-grupos formados pelas combinaes dos co valores dos dois factores. Assim por exemplo, 401 a soma do valor de breaks para as e linhas do conjunto de dados onde wool tem o valor A e tension o valor L. Uma outra funo interessante a funo sapply(), que permite aplicar uma funo ca e ca ca a todos os elementos de um vector ou lista. Vejamos dois exemplos ilustrativos, > x <- sample(10) > sapply(x, function(y) (y - mean(x))/sd(x)) [1] 1.1560120 -0.8257228 0.8257228 0.4954337 -0.1651446 [7] -1.1560120 0.1651446 -0.4954337 -1.4863011 1.4863011

A funo sapply ca

> l <- list(f1 = sample(20), f2 = c(2.3, 1.3, 4.5, 2.4), f3 = rnorm(100)) > sapply(l, quantile) f1 f2 f3 0% 1.00 1.300 -3.2453520 25% 5.75 2.050 -0.6011432 50% 10.50 2.350 0.1545809 75% 15.25 2.925 0.6604947 100% 20.00 4.500 2.3431545 No primeiro exemplo, aplicamos uma funo a um vector. Note, que a funo no ca ca a necessita de existir no R e pode mesmo ser denida na prpria chamada ao sapply(), o como o caso deste exemplo. Esta funo pode ser vista como temporria, uma vez e ca a que s existe durante a execuo do sapply(). No segundo exemplo, vemos a funo o ca ca quartile() a ser aplicada a uma lista. Disto resultada a aplicao a cada elemento da ca lista, originado neste caso uma matriz de resultados, com nomes apropriados aos mesmos. Para nalizar diga-se que a funo sapply() uma verso amigvel da funo ca e a a ca lapply(), cuja ajuda pode ser consultada para mais informaes. co
12 Na realidade o segundo argumento da funo pode ser um vector de dimenses, mas esse tipo de ca o utilizao sai fora do mbito deste texto. ca a

52

PROGRAMACAO EM R

3.3

Funoes c

Na linguagem R as funes so tambm objectos e podem ser manipuladas de forma co a e semelhante aos outros objectos que estudamos at agora. Uma funo tem trs caractee ca e r sticas principais: uma lista de argumentos, o corpo da funo e o ambiente onde ela ca e denida. A lista de argumentos uma lista de s e mbolos (os argumentos) separada por v rgulas, que podem ter valores por defeito. Existe ainda a possibilidade de um argumento ser o conjunto de caracteres ..., cujo signicado iremos descrever mais ` frente. a O corpo de uma funo formado por um conjunto de instrues da linguagem R, sendo ca e co que normalmente um bloco de instrues. Quanto ao ambiente da funo, trata-se do e co ca ambiente activo quando ela foi criada e isso determina que tipo de objectos so vis a veis pela funo conforme vermos mais ` frente. ca a 3.3.1
Criar funes co

Criar funes co

A criao de uma funo consiste na atribuio do contedo de uma funo a um nome, ca ca ca u ca como qualquer outro objecto do R. Esse contedo a lista dos seus argumentos e as u e instruo que formam o corpo da funo. Vejamos um exemplo simples de uma funo ca ca ca que recebe como argumento uma temperatura em graus Celsius e a converte para graus Fahrenheit, > cel2far <- function(cel) { + res <- 9/5 * cel + 32 + res + } > cel2far(27.4) [1] 81.32 > cel2far(c(0, -34.2, 35.6, 43.2)) [1] 32.00 -29.56 96.08 109.76

Note como, tirando partido da vectorizao das operaes aritmticas do R (c.f. Secca co e ca o 2.3), podemos usar a nossa funo com um vector de nmeros como argumento e ca u no s com um unico valor de temperatura. Repare ainda que o corpo desta funo est a o ca a desnecessariamente complexo, podendo ns em alternativa denir a funo como, o ca > cel2far <- function(cel) 9/5 * cel + 32 Em resumo, a criao de uma funo uma atribuio com a forma genrica, ca ca e ca e <nome da fun~o> <- function(<lista de argumentos>) <corpo da fun~o> ca ca
Valor retornado

O valor retornado como resultado da funo o resultado da ultima computao ca e ca efectuada na funo. No exemplo acima essa ultima computao o contedo do objecto ca ca e u res e portanto esse o resultado da funo. Existe uma funo espec e ca ca ca, a funo ca return(), que permite retornar um determinado valor numa funo. Isso quer dizer que ca essa funo se executada no corpo de uma funo vai fazer com que a execuo da mesma ca ca ca termine a imediatamente. Vejamos um exemplo, > calculo <- function(x) { + if (x < 0) + return(NULL) + y <- 34 * sqrt(x)/5.2 + y + } Se esta funo for chamada com um nmero negativo a condio do if verdadeira e ca u ca e portanto a funo return executada. O seu efeito terminar imediatamente a execuo ca e e ca da funo calculo, e retornar o valor NULL como resultado dessa execuo. Se a funo ca ca ca fr chamada com um nmero no negativo, ento a execuo segue o curso normal sendo o u a a ca nesse caso o contedo do objecto y que retornado como resultado da funo. u e ca

3.3

Funes co

53

3.3.2

Ambientes e scope de variveis a

Quando comeamos a nossa interaco com o R, por exemplo criando novos objectos c ca (vectores, matrizes, funes, etc.), estamos a faz-lo num ambiente chamado o workspace, co e ou o ambiente de topo. Sempre que fazemos ls() por exemplo, para saber os objectos que temos na memria, o que obtemos a lista de objectos neste ambiente de topo. o e Como vamos ver, existem situaes que levam ` criao de novos ambientes, levando a co a ca uma hierarquia de ambientes com a forma de uma rvore invertida, aninhados uns nos a outros, at ao ambiente de topo. A importncia destas noes reside nas regras de scope e a co ou visibilidade dos objectos em R que dependem do ambiente em que eles so denidos. a Quando criamos uma funo ela, como objecto que , ca associada ao ambiente onde ca e foi criada. Este normalmente o ambiente de topo, o tal workspace do R. No entanto, e quando chamamos essa funo o R vai execut-la num novo ambiente por baixo do ca a ambiente onde ela chamada. Quer isto dizer que o ambiente onde so executadas as e a instrues que formam o corpo de uma funo no o mesmo ambiente onde a funo co ca a e ca chamada. Isto tem impacto nos objectos que so vis e a veis em cada um destes dois ambientes, o ambiente de onde chamamos a funo, e o ambiente onde as instrues ca co da funo so executadas (que est em baixo do primeiro em termos da hierarquia de ca a a ambientes do R). Vejamos um exemplo das implicaes e importncia desta informao. co a ca Consideremos o seguinte cdigo, que inclui a denio de uma funo, e que assumimos o ca ca ser introduzido no ambiente de topo, > x <- 2 > z <- 56.3 > f <- function(x) { + a <- 34 + y <- x / 4 * a * z + y + } > f(21) [1] 10049.55 > a Error: Object "a" not found Este pequeno exemplo ilustra vrias questes importantes ligadas ` questo dos ama o a a bientes e tambm do scope ou visibilidade das variveis. Analisemos cada uma delas. e a O objecto a, por exemplo, criado dentro da funo f, ou seja a instruo de atribuio e ca ca ca que cria o objecto a, executada no ambiente da funo f que diferente do ambiente e ca e de topo, concretamente est abaixo deste. Essa a razo pela qual, quando no ambiente a e a de topo, pedimos o contedo do objecto a, obtemos um erro, indicando que no foi enu a contrado nenhum objecto com esse nome. O erro tem lgica uma vez que no ambiente o de topo no existe de facto, qualquer objecto com o nome a. Por outro lado, se antena tarmos de novo no cdigo da funo, vericaremos que existe uma atribuio que usa o o ca ca objecto z, objecto esse que no existe no ambiente da funo f. No entanto, ele existe no a ca ambiente acima deste na hierarquia de ambientes. E isto leva-nos ` regra fundamental a da avaliao de instrues na linguagem R, relativamente ` visibilidade do objectos. Esta ca co a regra, conhecida por lexical scoping, diz-nos que: Quando um objecto necessrio numa avaliao, ele procurado pelo R no e a ca e ambiente em que foi pedido. Caso seja encontrado um objecto com esse nome nesse ambiente, ele usado. Caso tal no acontea o R procura-o no ambiente e a c acima, e assim sucessivamente at ao ambiente de topo. Se neste processo for e encontrado um objecto com esse nome ele usado. De contrrio o R d um e a a erro dizendo que tal objecto no existe. a Assim, no ambiente da execuo da funo f, o objecto z no existe, no entanto, ca ca a no ambiente acima, o ambiente de topo, existe um objecto com o nome z e por isso o seu valor (56.3), usado na atribuio dentro da funo f. Por outro lado, na mesma e ca ca

Workspace

Scoping

A regra de lexical scoping

54

PROGRAMACAO EM R

instruo de atribuio dentro da funo f, referido um objecto com o nome x. O valor ca ca ca e que usado o valor do objecto com esse nome que existe na prpria funo (que por e e o ca sinal o seu unico argumento), e no o valor do objecto com o nome x que existe no e a ambiente de topo. Assim, no exemplo de chamada da funo mostrado acima, o valor de ca x usado na atribuio o valor 21 e no o valor 2. ca e a Estas so provavelmente as noes principais ligadas a ambientes e scoping da lina co guagem R. No entanto, existe muito mais por detrs destas importantes noes, como a co por exemplo funes espec co cas para lidar com ambientes, ou para aceder a objectos em ambientes espec cos. Tais assuntos saem no entanto fora do mbito deste texto. O a leitor interessado poder consultar por exemplo o livro S Programming por Venables and a Ripley (2000). 3.3.3 Argumentos de funes co

Valores por defeito

Quando criamos uma funo indicamos normalmente a sua lista de argumentos. Nesta ca altura a linguagem R permite-nos tambm explicitar, caso queiramos, um valor por defeito e para cada um desses argumentos. O uso desta facilidade, vai permitir ao utilizador das nossas funes, evitar incluir um valor para esses argumentos caso pretenda usar o valor co por defeito. Isto particularmente util em funes com muitos argumentos, alguns dos e co quais s usados em situaes muito particulares, sendo que os seus valores por defeito o co fazem sentido na maioria das utilizaes dessas funes. Por exemplo, a funo mean() co co ca serve para calcular a mdia dos valores que lhe so fornecidos, e a > mean(c(21, 45.3, 342.4, 54.3, 65.3, 1000.2)) [1] 254.75 A maioria das vezes iremos usar esta funo deste modo. No entanto, se consultarmos ca a ajuda desta funo iremos observar que ela tem outros dois argumentos, trim e na.rm, ca cada um deles com um valor por defeito, 0 e FALSE, respectivamente. O facto de eles terem um valor por defeito permite-nos fazer chamadas ` funo como a apresentada em a ca cima, sem que obtenhamos um erro por no termos indicado o valor destes argumentos. a Ao no indicarmos estes valores o R vai assumir os valores por defeito indicados pelo a criador da funo nos clculos executados dentro da mesma. Se no pretendessemos usar ca a a estes valores, teriamos que o explicitar na chamada ` funo, como no exemplo a seguir, a ca > mean(c(21, 45.3, 342.4, 54.3, 65.3, 1000.2), trim = 0.2) [1] 126.825 Use a ajuda da funo para ver se entende o que foi calculado com este valor do ca parmetro trim. a Em resumo, ao criarmos uma funo podemos indicar valores por defeito para alguns ca dos seus parmetros, bastanto para isso usar o sinal igual seguido do valor ` frente do a a nome do argumento, conforme ilustrado neste pequeno exemplo, > + + + + + + > > valor.central <- function(x, estat = "mean") { if (estat == "mean") return(mean(x)) else if (estat == "median") return(median(x)) else return(NULL) } x <- rnorm(10) valor.central(x)

Valores por defeito

[1] 0.4182037 > valor.central(x, estat = "median")

3.3

Funes co

55

[1] 0.4513049 Uma outra facilidade bastante conveniente da linguagem R a possibilidade de criar e funes com nmero varivel de parmetros. Isso conseguido por um parmetro especial co u a a e a que indicado por .... Este parmetro especial de facto uma lista que pode agregar e a e um nmero qualquer de parmetros usados na chamada da funo. Uma utilizao u a ca ca frequente desta facilidade na criao de funes que chamam outras funes e ao faze ca co co e lo pretendem passar-lhes parmetros que s a elas lhes interessam. Por exemplo, no a o exemplo da funo valor.central mostrada acima, no previmos a possibilidade de o ca a utilizador ao calcular o valor central usando a funo mean() pretender faz-lo usando ca e um mdia truncada dos 20% valores extremos. Tal poss atravs do parmetro trim e e vel e a da funo mean(), mas da forma como criamos a funo valor.central(), o utilizador ca ca no tem forma de usar a funo mean deste modo. Do mesmo modo a funo median(), a ca ca que tambm pode ser chamada da funao que criamos, tambm tem parmetros prprios e c e a o que so inacess a veis ao utilizador da nossa funo. Uma forma de dar a volta a este ca problema reside exactamente na utilizao do parmetro ..., como vemos nesta denio ca a ca alternativa de valor.central(), > + + + + + + > > valor.central <- function(x, estat = "mean", ...) { if (estat == "mean") return(mean(x, ...)) else if (estat == "median") return(median(x, ...)) else return(NULL) } x <- rnorm(10) valor.central(x)

umero varivel de a

rmetros a

[1] 0.1530552 > valor.central(x, trim = 0.2) [1] 0.2216488 > valor.central(x, estat = "median", na.rm = T) [1] 0.1385397 Desta forma, tudo o que no sejam parmetros espec a a cos da funo valor.central() ca so agregados no tal parmetro especial ..., que por sua vez passado para as chamaa a e das das funes mean e median, com qualquer que seja o seu contedo. Desta forma co u conseguimos, por exemplo, obter um valor central calculado com a funo mean(), mas ca que seja uma mdia truncada dos 20% valores extremos, como vemos no exemplo acima. e Existem ainda outras utilizaes deste parmetro especial, mas mais uma vez esto co a a fora do mbito deste texto, pelo que o leitor interessado dever consultar bibliograa a a mais avanada sobre a linguagem R. c Para alm das questes ligadas aos parmetros formais (os parmetros usados na e o a a denio da funo), que descrevemos at agora, existem ainda questes ligadas aos ca ca e o parmetros actuais (os usados nas chamadas `s funes), que agora detalhamos. a a co Em particular, como j vem acontecendo em diversos exemplos fornecidos ao longo a deste texto, existem duas formas de indicar os valores dos parmetros com os quais a pretendemos chamar uma qualquer funo: atravs de posio, ou por nome. ca e ca Uma chamada por posio ocorre quando pretendemos que o valor indicado na posica ca o x da lista de argumentos da funo seja associado ao argumento formal na mesma ca posio. Por exemplo, ao executar seq(10,23) o R vai assumir que o valor 10 para ca e ser atribu ao primeiro argumento formal da funo seq() (o argumento from no caso, do ca conforme pode conrma na ajuda da funo), e o valor 23 no segundo argumento formal ca (o argumento to). Isto leva a obter uma sequncia de nmeros de 10 a 23, de 1 em 1. e u

Parmetros formais a e actuais

56

PROGRAMACAO EM R

J a chamada seq(10,length=23) tem um resultado completmente diferente, uma vez a que o segundo valor indicado por nome e no por posio como no exemplo anterior. e a ca Isto quer dizer que o nmero 23 no atribu ao argumento na segunda posio, como u a e do ca anteriormente, mas sim ao argumento formal com o nome length. A utilizao da chamada por nome, alm de mais clara, por vezes indispensvel, ca e e a nomeadamente em funes com muitos argumentos, a maioria com valores por defeito, co em que o utilizador pretende usar um valor diferente num dos argumentos do m da lista de argumentos formais. Sem esta facilidade o utilizador iria ter que preencher todos os outros argumentos at chegar ao argumento que pretende alterar. Com a chamada e por nome, basta-lhe proceder como vimos no exemplo de cima, indicando o nome do argumento formal e o valor que pretende usar. 3.3.4 Lazy evaluation

O que a lazy e evaluation?

e ca Conforme j foi mencionado na Seco 3.3.2, sempre que chamada uma funo o R cria a ca um novo ambiente por baixo do ambiente onde a chamda foi efectuada. Nessa altura as expresses dos argumentos actuais so vericadas sintaticamente, mas no so avaliadas. o a a a A este procedimento chama-se lazy evaluation. Os argumentos actuais s so avaliados o a quando so necessrios pela primeira vez no corpo da funo. Esta regra pode ter por a a ca vezes implicaes inexperadas conforme ilustrado nestes pequenos exemplos: co > f1 <- function(a1, a2 = sqrt(a1)) { + a1 <- a1^2 + a2 + } > f1(4) [1] 4 > f2 <- function(a1, a2 = sqrt(a1)) { + z <- a2/a1 + a1 <- a1^2 + a2 + } > f2(4) [1] 2 Na primeira funo, embora o argumento a2 seja denido com uma valor por defeito ca igual ` ra quadrada do primeiro argumento, quando chamamos a funo com o valor a z ca 4, poder amos estar ` espera que o argumento a2 (que por sinal o valor retornado pela a e funo), tomasse o valor 2. Todavia, devido ` lazy evaluation, a expresso sqrt(a1) s ca a a oe calculada quando necessrio no corpo da funo, e isso s acontece na ultima instruo. a ca o ca Acontece que nessa altura a1 j no 4 mas sim 16, devido ` primeira instruo do corpo a a e a ca da funo, e portanto sqrt(a1) vai dar 4 e no 2 como poder ca a amos esperar. J na segunda funo, porque a2 necessrio na primeira instruo, logo a inicialia ca e a ca e zado com o valor sqrt(a1), que nessa altura igual a 2. Da o resultado diferente desta e segunda funo. ca 3.3.5 Algumas funes uteis co

O R possui uma enorme quantidade de funes. Nesta seco apresentamos uma brev co ca ssima resenha de algumas funes uteis, agrupadas pelo seu tipo de funcionalidade. Esta co lista est obviamente muito longe de ser exaustiva. a Algumas estat sticas bsicas a

3.3

Funes co

57

sum(x) max(x) min(x) which.max(x) which.min(x) range(x) length(x) mean(x) median(x) sd(x) var(x) quantile(x) scale(x)

Soma dos elementos do vector x. Mximo dos elementos de x. a M nimo dos elementos de x. O ndice do maior valor em x. O ndice do menor valor em x. O range de valores em x (produz o mesmo resultado que c(min(x),max(x))). O nmero de elementos em x. u A mdia dos valores em x. e A mediana dos valores em x. O desvio padro dos elementos em x. a A varincia dos elementos em x. a Os quartis de x. Normaliza os elementos em x, i.e. subtrai a mdia e divide pelo desvio-padro, resule a tando num vector de nmeros com mdia zero u e e desvio-padro unitrio. Tambm funciona a a e com data frames (s as colunas numricas, obo e viamente).

Algumas operaes vectoriais e matemticas co a

sort(x) rev(x) rank(x) log(x,base) exp(x) sqrt(x) abs(x) round(x,n) cumsum(x) cumprod(x) match(x,s)

union(x,y) intersect(x,y) setdiff(x,y) is.element(x,y) choose(n,k)

Elementos de x ordenados. Inverte a ordem dos elementos em x. Faz o ranking dos elementos de x. Calcula o logaritmo na base base de todos os elementos de x. Calcula o exponencial dos elementos de x. Raiz quadrada dos elementos de x. Valor absoluto dos elementos de x. Arredonda os valores em x para n casas decimais. Obtm um vector em que o elemento i a e e soma dos elementos x[1] at x[i]. e O mesmo para o produto. Obtm um vector com o mesmo tamanho de x, e contendo os elementos de x que pertencem a s. Os elementos que no pertencem a s aparecem a no resultado assinalados com o valor NA. Obtm um vector com a unio dos vectores x e a e y. Obtm um vector com a interseco dos vece ca tores x e y. Obtm um vector resultante de retirar os elee mentos de y do vector x. Retorna o valor TRUE se x est contido no a vector y. Calcula o nmero de combinaes k, n a n. u co

Algebra Matricial

58

PROGRAMACAO EM R

diag(x,nrow,ncol)

t(x) nrow(x) ncol(x) A %*% B solve(A,b)

qr(x) svd(x) eigen(x) det(x)

Constri uma matriz diagonal com nrow linhas o e ncol colunas, usando o nmero x. Tamu bm pode ser usada para extrair ou substituir e os elementos na diagonal de uma matriz (ver exemplos fazendo ? diag). A matriz transposta de x. Nmero de linhas de x. u Nmero de colunas de x. u Multiplicao matricial de A por B. ca Resolve o sistema de equaes lineares Ax = b. co Com um unico argumento (uma matriz) (e.g. solve(A)) calcula a sua inversa. Decomposio QR da matriz x. ca Decomposio SVD (singular value decompoca sition) da matriz x. Valores e vectores prprios da matriz quao drada x. O determinante da matriz quadrada x.

3.4

Objectos, Classes e Mtodos e

Esta seco inclui informao que sai um pouco fora do mbito introdutrio deste texto. ca ca a o De facto, existe muito para dizer sobre estes tpicos no contexto da linguagem R. Todavia, o mesmo tratando-se de uma introduo, h questes relacionadas com estes tpicos que ca a o o qualquer utilizador do R deve conhecer. A maioria dos objectos que vimos at agora tem uma estrutura relativamente sime ples. Todavia, poss em R constru novos tipos (classes) de objectos, usando estes e vel r tipos elementares que temos vindo a descrever. Por exemplo, existem funes em R que co retornam como resultado um modelo de um conjunto de dados (por exemplo uma rede neuronal). Tal objecto tem uma complexidade bem maior do que os que estudamos at e agora, no deixando no entanto de ser um objecto como outro qualquer do ponto de vista a do R. Isto quer dizer que por exemplo pode fazer sentido perguntar ao R qual o contedo u deste objecto complexo. Para tal ser poss vel, e de forma transparente para o utilizador, conveniente que a pessoa que decidiu criar tais objectos complexos, indique tambm ao e e R como mostr-los ao utilizador. Traduzido de outro modo, o utilizador dever indicar a a ao R um mtodo para mostrar um objecto da classe que acabou de criar. e Muita desta aparente complexidade, pode ser escondida do utilizador comum. Por exemplo, a funo summary() produz um sumrio do contedo do objecto que lhe ca a u e fornecido como argumento. O signicado deste sumrio, bem como a forma como ele a e obtido, est em grande parte dependente do tipo de objecto de que queremos o sumrio. a a No entanto o utilizador no precisa de saber isso. Vejamos um exemplo concreto deste a comportamento, > x <- rnorm(10) > summary(x) Min. 1st Qu. Median -1.3790 -0.2195 -0.1066 Mean 3rd Qu. 0.1157 0.8568 Max. 1.3760

> summary(matrix(x, 5, 2)) V1 Min. :-0.6689 1st Qu.:-0.1069 Median :-0.1062 Mean : 0.3167 3rd Qu.: 1.0894 Max. : 1.3758 V2 Min. :-1.37895 1st Qu.:-0.25349 Median :-0.11738 Mean :-0.08521 3rd Qu.: 0.15905 Max. : 1.16472

3.4

Objectos, Classes e Mtodos e

59

Repare como duas chamadas ` mesma funo (na realidade s aparentemente a mesma a ca o como veremos), produzem resultados diferentes dependendo da classe do objecto dado como argumento, embora conceptualmente ambos sejam sumrios desse argumento. De a facto, a funo summary() uma funo genrica, que basicamente o que faz ver a classe ca e ca e e do objecto que lhe passado como argumento, e depois despacha a tarefa de produzir e o sumrio para funes especializadas nessa classe de objectos. Para isso, obviamente a co e preciso que algum tenha escrito essas funes especializadas, ou seja que algum tenha e co e fornecido uma mtodo summary para a classe de objectos em causa (no caso do exemplo e um vector e uma matriz). Podemos rapidamente conrmar isto que se est a passar por a detrs da funo summary() executando o seguinte, a ca > methods(summary) [1] summary.aov [4] summary.data.frame [7] summary.ecdf* [10] summary.infl [13] summary.manova [16] summary.nls* [19] summary.POSIXlt [22] summary.princomp* [25] summary.table

Funes genricas co e

Mtodos e

summary.aovlist summary.Date summary.factor summary.lm summary.matrix summary.packageStatus* summary.ppr* summary.stepfun summary.tukeysmooth*

summary.connection summary.default summary.glm summary.loess* summary.mlm summary.POSIXct summary.prcomp* summary.stl*

Non-visible functions are asterisked A funo methods() mostra a lista de mtodos (isto funes especializadas em ca e e co classes particulares) que existem para a funo genrica summary(). Podemos ver, por ca e exemplo que existe uma funo summary.matrix(), que como o nome indica, a funo ca e ca usada para produzir sumrios para objectos da classe matrix. a Esta caracter stica da linguagem R, e das linguagens orientadas aos objectos genericamente, bastante conveniente, uma vez que permite uma interaco com o utilizador e ca mais transparente. A este, basta-lhe saber que a funo summary() produz sumrios de ca a objectos, sejam eles de que tipo forem, no necessitando por exemplo de conhecer todas a as funes espec co cas que existem para produzir os sumrios para cada classe de objecto. a A funo class() permite-nos saber qual a classe de um qualquer objecto, ca > x <- rnorm(10) > class(x) [1] "numeric" > class(matrix(x, 5, 2)) [1] "matrix" > class(as.POSIXct("2006-9-23")) [1] "POSIXt" "POSIXct"
Criar um nova classe

Classes

Para criarmos uma nova classe basta-nos criar uma funo que possa ser usada para ca criar essa classe de objectos e depois podemos escrever funes que implementem alguns co mtodos que sejam uteis para objectos dessa nova classe. e Vejamos um exemplo deste processo criando uma nova classe de objectos que vise armazenar dados sobre pessoas. Para simplicar vamos assumir que um objecto da classe pessoa formado por um nome, os nomes dos pais, a data de nascimento e o e sexo da pessoa. > pessoa <- function(n, p, d, s) { + p <- list(nome = n, pais = p, nascimento = d, sexo = s) + class(p) <- "pessoa"

60

PROGRAMACAO EM R

+ p + } > chefe <- pessoa("Ana", list(pai = "Carlos", mae = "Joana"), as.Date("1970-03-3"), + "f") > class(chefe) [1] "pessoa" Repare como, depois de criar a funo pessoa(), podemos us-la para criar objectos ca a da classe pessoa. E este o caso do objecto chefe que como vemos tem essa classe. Em seguida podemos ver como criar uma funo para implementar o mtodo de ca e sumarizao de objectos da classe pessoa. ca > summary.pessoa <- function(p) cat("O meu nome ", p$nome, " e sou ", e + ifelse(p$sexo == "f", "filha", "filho"), " de ", p$pais$pai, + " e ", p$pais$mae, " tendo nascido a ", format(p$nascimento, + "%d %b %Y"), "\n") > summary(chefe) O meu nome e Ana e sou filha de Carlos e Joana tendo nascido a 03 Mar 1970

Aps a criao deste mtodo passamos a poder usar a funo summary() aplicada a o ca e ca objectos da classe pessoa. Uma vez que criamos a funo summary.pessoa(), quando ca chamamos summary(chefe), o R vai comear por ver qual a classe do objecto chefe e, c uma vez que essa pessoa, vai procurar uma funo com o nome summary.pessoa(). e ca Assim, se pretendemos criar uma mtodo espec e co para a classe pessoa para uma funo genrica qualquer xpto, o que temos que fazer criar a funo xpto.pessoa. ca e e ca Por exemplo, se pretendessemos aplicar a funo genrica plot() a objectos da classe ca e pessoa, precisariamos de criar uma funo chamada plot.pessoa(). ca

3.5
O que ? e

Depurao de Programas em R ca

A depurao de programas em qualquer linguagem (debugging) de programao tem ca ca como objectivo principal encontrar a fonte de erros ou comportamentos imprevistos nos programas que desenvolvemos. O R possui vrias funes que podem ser utilizadas para ajudar nesta tarefa. Uma a co delas a funo traceback() que permite ao utilizador obter a sequncia de funes que e ca e co foram chamadas at o erro ocorrer. e Se tal no fr suciente para identicar a fonte do erro, ou ento se localizamos a a o a sua poss origem mas no entendemos o porqu do erro, poderemos tambm socorrervel a e e mo-nos da funo browser(). Esta funo se introduzida no cdigo de uma funo ca ca o ca onde suspeitamos existir algo de errado, far com que a partir da sua posio, todas as a ca instrues seguintes sejam executadas passo a passo e unicamente sob a nossa ordem. Ou co seja, depois de encontrar browser() o R vai parar e s executar a instruo seguinte o a ca quando ns mandarmos, parando logo em seguida de novo. Em cada uma destas paragens o o R vai mostrar um prompt especial onde o utilizador poder fazer quase tudo o que a pode fazer no prompt normal do R (por exemplo ver o contedo de objectos da funo u ca a ser depurada), mas onde existem ainda sertos comandos especiais ligados ` funo a ca browser(). Vejamos um pequeno exemplo deste tipo de depurao. Suponhamos que temos a ca seguinte funo, que aparenta estar sem problemas, ca > er <- function(n,x2) { + s <- 0 + for(i in 1:n) { + s <- s + sqrt(x2) + x2 <- x2-1 + }

3.5

Depurao de Programas em R ca

61

+ s + } > er(2,4) [1] 3.732051 Suponhamos agora que fazemos a seguinte chamada que inesperadamente produz um aviso sobre um erro numrico (NaN signica Not A Number ) na execuo da funo, e ca ca > er(3,1) [1] NaN Warning message: NaNs produced in: sqrt(x2) Vamos incluir uma chamada ` funo browser() no corpo da funo antes do local a ca ca que suspeitamos ser a fonte do aviso. Voltamos a fazer a mesma chamada e usamos ento a as facilidades da execuo passo a passo, como vemos a seguir, ca > er <- function(n,x2) { + s <- 0 + browser() + for(i in 1:n) { + s <- s + sqrt(x2) + x2 <- x2-1 + } + s + } > er(3,1) Called from: er(3, 1) Browse[1]> x2 [1] 1 Browse[1]> print(n) [1] 3 Browse[1]> n debug: for (i in 1:n) { s <- s + sqrt(x2) x2 <- x2 - 1 } Browse[1]> n debug: i Browse[1]> i NULL Browse[1]> n debug: s <- s + sqrt(x2) Browse[1]> i [1] 1 Browse[1]> s [1] 0 Browse[1]> sqrt(x2) [1] 1 Browse[1]> debug: x2 <- x2 - 1 Browse[1]> s [1] 1 Browse[1]> debug: i Browse[1]> x2 [1] 0 Browse[1]>

62

PROGRAMACAO EM R

debug: s <- s + sqrt(x2) Browse[1]> i [1] 2 Browse[1]> sqrt(x2) [1] 0 Browse[1]> debug: x2 <- x2 - 1 Browse[1]> debug: i Browse[1]> debug: s <- s + sqrt(x2) Browse[1]> sqrt(x2) [1] NaN Warning message: NaNs produced in: sqrt(x2) Browse[1]> x2 [1] -1 Browse[1]> Q > Quando chamamos de novo a funo o R pra quando encontra a instruo browser() ca a ca fazendo aparecer um prompt com a forma genrica Browse[i]>. A partir daqui est nas e a nossas mos o que pretendemos fazer. Tipicamente comeamos por inspeccionar o valor a c dos objectos da funo para ver se econtramos algo suspeito que possa estar a orginar o ca erro. Nesta sesso exemplo comeamos por interrogar o R sobre o valor dos parmetros, x2 a c a e n. No caso deste ultimo, repare que usamos a construo print(n) e no simplesmente ca a o nome do objecto como zemos para o x2. A explicao para isto reside no facto de neste ca ambiente de debugging o n seguido de Enter tem um signicado especial que dizer ao e R, podes avanar para a prxima instruo, que foi o que zemos a seguir. O mesmo c o ca efeito pode ser conseguido carregando unicamente na tecla Enter. E por a continuamos at que reparamos que o erro est a ser originado por uma chamada sqrt(x2), e quando e a perguntamos o valor de x2 na altura da chamada que deu o erro, vericamos que ele -1, e e da o erro uma vez que o R no sabe calcular ra a zes quadradas de nmeros negativos. u Ou seja, a nossa funo vai decrementando o valor de x2, dentro do ciclo e se este fr ca o executado bastantes vezes o x2 acabar por car negativo, em particular se fr inferior a o a n que o par`metro que controla o nmero de execues do ciclo. Descoberto o erro e a u co podemos abortar este ambiente de debugging usando o comando Q. Um outro comando deste ambiente de debugging que por vezes util o comando c. Se executado quando e e o debugger est dentro de um ciclo, faz com que o R deixe execute o resto das iteraes a co do mesmo at ao m, sem qualquer interrupo s voltando a aparecer o prompt no m e ca o destas. Em vez de alterar a funao que pretendemos depurar, podemos simplesmente fazer c debug(er) e depois fazer a chamada problemtica, er(3,1). A intereaco que se segue a ca em tudo idntica ` que vimos acima. Note-se que at fazermos undebug(er), sempre e e a e que voltamos a chamar a funo er() o R entra em modo de debugging. A vantagem ca da funo browser() em relao a esta alternativa que podemos iniciar o debugging no ca ca e ponto da funo que queremos, enquanto que com esta alternativa ele comea logo deste ca c a primeira instruo da funao. ca c

63

Manipulao de Dados ca

O R tem vrios objectos onde podemos armazenar diversos tipos de dados. No entanto, a conforme j mencionado, so os data frames que se revelam como os mais adequados para a a a e armazenar tabelas de dados de um problema qualquer. Na Seco 2.10 vimos j o que ca um data frame, como os criar, bem como algumas operaes essenciais para a sua manico pulao. Nesta seco iremos analisar mais algumas questes importante para analisar ca ca o dados guardados em data frames usando as potencialidades do R. Nomeadamente iremos ver: como carregar dados de vrias fontes para um data frame, como obter sumrios das a a propriedades principais dos dados, e tambm tcnicas para visualizar esses dados. e e Antes de abordarmos estes tpicos s uma pequena nota sobre o facto de o R ter o o j dispon a veis diversas tabelas de dados que poderemos usar para por exemplo testar as nossas capacidades com a linguagem. Alm disso, a maioria das packages extra que e vamos instalando vem tambm com mais conjuntos de dados para ilustrar algumas das e suas funcionalidades. Para sabermos os dados que esto actualmente (isto com as a e packages neste momento carregadas) dispon veis, podemos fazer: > data() Como resultado -nos apresentada um lista com os nomes e breves descries dos e co conjuntos de dados dispon veis. Podemos obter mais informao sobre qualquer um ca deles, usando as funes de ajuda aplicadas ao nome do conjunto de dados, como se de co uma funo se tratasse. ca Se pretendermos usar algum dos conjuntos de dados podemos usar a mesma funo, ca > data(cars) O efeito disto criar um data frame com o nome cars contendo este conjunto de e dados.

Dados que vm com e o R

4.1

Carregar dados para o R

Nesta seco iremos analisar formas de clocar em data frames, dados que se encontram ca armazenados noutras plataformas e que, pela sua dimenso, no faz sentido introduzi-los a a de novo ` mo no R. Dito de outra forma, iremos ver como importar dados para o R. a a 4.1.1 De cheiros de texto

Os cheiros de texto so uma das formas mais comum de armazenar dados. Para alm a e disso, existem ainda diversas plataformas que permitem exportar dados armazenados nas suas estruturas prprias, para cheiros de texto em formatos particulares, como por o exemplo o formato CSV. Esta muitas vezes a forma mais simples de importar para o R e os dados de uma aplicao qualquer, que use um formato mais fora de vulgar. ca O formato mais comum de armazenar uma tabela de dados num cheiro de texto consiste em pr cada linha da tabela de dados numa linha separada do cheiro, e fazer o separar os valores de cada coluna de uma linha, por um qualquer caracter separador. Relativamente a este ultimo, escolhas comuns so a v a rgula (levando ao formato CSV, Comma Separated Values)), o ponto e v rgula, ou o caracter tab. A funo principal do ca R para ler este tipo de cheiros a funo read.table(). Esta funo tem inmeros e ca ca u parmetros que permitem ajustar a importao aos detalhes particulares do formato dos a ca dados no cheiro que pretendemos carregar. Entre eles, est obviamente uma parmetro a a que permite explicitar o separador dos valores que usado (o parmetro sep) no cheiro. e a Por defeito, o seu valor white space, que inclui um ou mais caracteres de espao e tabs. e c E poss explicitar outro separador, como por exemplo a v vel rgula. Todavia, por vrias a destas alternativas serem muito comuns, existem outras funes que so essencialmente co a iguais ` read.table(), sendo que a diferena fundamental est no separador por defeito a c a que assumido bem como noutros pequenos detalhes relacionados com os defaults. E e esse o caso das funes read.csv(), read.csv2(), read.delim() e read.delim2(). Para co

Formato CSV

A funo read.table ca

64

MANIPULACAO DE DADOS

ver todos os detalhes das pequenas diferenas entre elas aconselhamos a leitura da ajuda c dessas funes que, pela sua semelhana, est toda junta. co c a Vejamos um pequeno exemplo de como usarmos uma destas funes. Suponhamos co que temos um cheiro de texto com dados, de que mostramos as primeiras linhas, ID;Nome;Nota 434;Carlos;13.2 523;Ana;15.1 874;Susana;4.8 103;Joaquim;15.9 ... Olhando para o cheiro com ateno poderemos reparar que os valores so separados ca a por ponto e v rgula, os nmeros reais usando o ponto como separador das casas decimais, u e o cheiro inclui o nome das colunas na primeira linha. Todas estas particularidades tm correspondncia em parmetros das funo de leitura que mencionamos acima. Se e e a ca pretendessemos usar a funo read.table() para ler este cheiro, deveriamos fazer: ca dados <- read.table('ficheiro.txt',header=T,sep=';',dec=',') O parmetro header permite-nos indicar se o cheiro tem, ou no, o nome das colunas a a na primeira linha de dados. O parmetro sep permite conforme j mencionado, indicar a a o separador de valores usado no cheiro. Finalmente o parmetro dec permite indicar a o caracter usado como separador de casas decimais dos nmeros reais. Note-se que este u formato bastante vulgar, sendo que uma das funes mencionadas usa estes valores e co como valores por defeito, e portanto seria mais prtico, neste caso particular, fazer, a dados <- read.csv2('ficheiro.txt') Estas so as funes principais para ler cheiros de texto no R. Existem ainda outras a co possibilidades, embora menos usadas, das quais destacar amos s a funo read.fwf(), o ca que permite ler cheiros que usem um formato de tamanho xo. Deixamos ainda uma breve nota sobra a leitura de cheiros muito grandes (dezenas de milhares de linhas e centenas de colunas). Nestas situaes, e assumindo que os dados cabem na memria co o do computador que se est a usar, as funes do tipo read.table() podero mostrar-se a co a demasiado lentas. Nestas situaes recomenda-se que se considere a utilizao da funo co ca ca scan(), de uso menos intuitivo, mas bastante mais eciente em termos computacionais. 4.1.2 Da Internet

Ler cheiros muito grandes Ler cheiros muito grandes

Por vezes existem dados que nos interessam que esto acess a veis em pginas da Internet. a Para sabermos qual a melhor forma de os importar para o R temos que analisar com cuidado o formato em que so fornecidos. Existem aqui vrias possibilidades. Se os dados esa a to fornecidos como um cheiro de texto com um formato qualquer (por exemplo CSV), e a o que nos do o URL para esse local (por exemplo http://www.blabla.com/dados.txt), a e ento a melhor forma de proceder fazer o download dos dados para um cheiro local, e a e depois proceder de alguma das formas indicadas na Seco 4.1.1. Para fazer o download ca do cheiro, poderemos ou abrir um browser e usar alguma opo do gnero Save As..., ca e ou ento fazer tudo dentro do R. Para isso poderemos usar a funo download.file(). a ca Vejamos,
> download.file('http://www.blabla.com/dados.txt','c:\\My Documents\\dados.txt')

O primeiro argumento indica o URL, e o segundo o nome do cheiro local no nosso computador onde os dados devem ser guardados. Note que se indicar um caminho para o cheiro, como no exemplo acima, dever separar o nome das pastas por dois caracteres a \\ e no um s como estaria ` espera. a o a Se o URL apontar para uma pgina Web normal (que escrita na linguagem HTML), a e no to fcil importar os dados para o R. Por exemplo, a pgina poderia mostrar uma a e a a a

4.1

Carregar dados para o R

65

tabela, no meio de outra informao, cujo contedo gostariamos de importar para o R. ca u Nestes casos necessrio importar toda a pgina (em HTML) e depois interpretar o e a a contedo dessa pgina para da extra a informao da tabela. Realizar essa tarefa u a r ca e poss em R, nomeadamente tirando partido de funes existentes na package XML, vel co mas no entanto sai fora do mbito deste texto. a 4.1.3 Do Excel

Em muitas organizaes comum usar o Excel para armazenar tabelas de dados. Existem co e vrias possibilidades para importar os dados para o R. Um consiste em gravar os dados a do Excel para um cheiro CSV, com as facilidades que o Excel tem para isso, e depois usar alguma das funes da Seco 4.1.1. co ca Uma outra possibilidade utilizar a funo read.xls() dispon na package gdata. e ca vel Esta funo permite explicitar o nome da folha de clculo e o nmero da worksheet ca a u contendo os dados que pretendemos importar, dados <- read.xls('dados.xls', sheet=3) Finalmente, poss usar o clipboard do Windows 13 , para fazer a importao dos e vel ca dados. Em concreto, podemos seleccionar a tabela de dados no Excel, fazer Edit+Copy, e depois, j no R, fazer: a dados <4.1.4 De bases de dados

As bases de dados so as infraestruturas por excelncia para armazenar dados, particua e larmente quando de grande dimenso, no contexto das organizaes. Neste contexto, no a co a ser surpreendente descobrir que o R tem vrias facilidades para fazer o interface com a a este tipo de software, tanto para importar dados como para exportar dados do R para uma base de dados. O R tem uma package chamada DBI que implementa uma srie de funes de interface e co com bases de dados. Estas funes so independentes do sistema de gesto de bases de co a a dados (SGBD) que estamos a usar, sendo o seu objectivo exactamente tornar o cdigo em o R independente (ou pelo menos o mais poss vel) desse software. A meno ao SGBD a ca usar feita unicamente quando se faz a ligao entre o R e esse software, sendo tudo o resto e ca independente de qualquer que seja o SGBD usado. Para tornar tudo isto poss vel, para alm da package DBI, precisamos ainda de outras packages associadas a cada um dos e SGBDs que pretendemos de facto usar. Por exemplo, se pretendemos fazer o interface com uma base de dados guardada em Oracle, temos que instalar tambm a package e ROracle. A ideia geral desta arquitectura de comunicao entre o R e os SGBDs pode ca ser melhor descrita pela Figura 7.
DBMS ODBC Driver (MyODBC) DBMS (MySQL)

Protocolo ODBC

R ODBC Driver (RODBC)

MySQL Driver (RMySQL) Database Interface (DBI) R

DBMS (ORACLE)

ORACLE Driver (RORACLE)

DBMS (Xpto)

XPTO Driver

Figura 7: A arquitectura de comunicao entre o R e diferentes SGBDs. ca


13 Note

que esta estratgia espc e e ca a verses Windows do R. o

66

MANIPULACAO DE DADOS

Ou seja a maioria do tempo o utilizador s v as funes da package DBI, e portanto o e co para ele tudo praticamente igual independentemente do SGBD que se est a usar como e a fonte de dados. Neste texto vamos ver um exemplo concreto usando o SGBD MySQL, um excelente SGBD de carcter gratu como o R. A melhor forma de fazermos o interface com este a to SGBD depende da plataforma onde estamos a trabalhar com o R. No Windows melhor e usar o protocolo ODBC, enquanto que noutras plataformas mais fcil usar o package e a RMySQL. A ideia de usar o protocolo ODBC est descrita na Figura 7. Temos o a package genrico DBI que vai falar com o package RODBC que tambm precisamos e e de instalar. Este por sua vez vai falar com as bases de dados no MySQL atravs de e um driver que precisamos instalar no Windows que de uma forma simplista traduz a linguagem do protocolo ODBC para algo entend pelo SGBD MySQL. vel Da primeira vez que pretendemos fazer o interface a uma base de dados no MySQL usando o protocolo ODBC, so necessrios alguns passos extra. Estes passos s so a a o a efectuados da primeira vez. Em particular precisamos de instalar o driver ODBC do MySQL que podemos obter no site deste SGBD (http://www.mysql.com). Depois de termos este driver (myodbc o seu nome) instalado, j podemos fazer ligaes ao e a co MySQL usando o protocolo ODBC. De acordo com este protocolo cada ligao a uma ca base de dados tem um nome (o Data Source Name, ou DSN na linguagem ODBC). Este nome vai ser usado para nos referirmos ` base de dados quando pretendermos a importar dados do lado do R. Para criar uma ligao ODBC em Windows temos de usar ca um programa chamado ODBC data sources que est dispon a vel no Control Panel do Windows. Depois de excutar este programa temos que criar uma nova User Data Source que use o MySQL ODBC driver (myodbc) que instalamos anteriormente. Durante este processo de criao vo-nos ser perguntadas vrias coisas como por exemplo o endereo ca a a c do servido MySQL (tipicamente localhost se o servidor est a ser executado no seu a computador), o nome da base de dados que pretendemos aceder, e tambm o nome e que pretendemos dar a esta ligao (o tal nome que depois vamos usar no R). Assim ca que este processo esteja completo, que voltamos a referir s feito a primeira vez que oe pretendemos criar uma ligao a um determinada base de dados, estamos prontos a, ca desde o R, establecer ligaes ` base de dados usando o protocolo ODBC. O exemplo co a que mostramos em seguida, establece uma ligao a um base de dados, para a qual ca anteriormente criamos uma ligao ODBC (DSN) com o nome teste, ca > > > > > > > library(RODBC) library(DBI) drv <- dbDriver('ODBC') ch <- dbConnect(drv,'teste','xpto','passwordxpto') dados <- dbGetQuery(ch,'select * from tabela') dbDisconnect(ch) dbUnloadDriver(drv)

As primeiras duas instruoes carregam as packages necessrias para importar os dac a dos. As duas seguintes establecem a ligao ` base de dados, sendo usado o DSN que ca a criamos no programa ODBC Data Sources, bem como introduzido o nosso nome de utilizador e respectiva password para podermos aceder ` base de dados do MySQL. Em a seguida vem a instruo principal para irmos importar dados de qualquer tabela da nossa ca base de dados14 . Neste caso estamos a importar todos as linhas e colunas de uma tabela chamada tabela da nossa base de dados. Note-se que para conseguirmos lidar com este tipo de bases de dados relacionais vamos precisar de saber SQL, que a linguagem de e consulta por excelncia deste tipo de bases de dados. O resultado da funo dbQuery() e ca um data frame. e Finalmente, as ultimas instrues fecham a ligao ` base de dados. Note-se que co ca a a package DBI dene ainda vrias outras funes que permitem, por exemplo, fazer a a co
14 Note-se que esta instruo j completamente independente do SGBD que estamos a usar e seria ca a e portanto igual para qualquer outro sistema que no o MySQL. a

4.2

Sumarizao de dados ca

67

operao inversa, ou seja enviar dados de um data frame do R para uma tabela de uma ca base de dados.

4.2

Sumarizao de dados ca

Assim que temos os nossos dados no R, usando algum dos processos indicados, podemos comear a analis-los. Nesta seco descrevemos algumas funes que indicam algumas c a ca co caracter sticas dos nossos conjuntos de dados. Para efeitos de ilustrao destas funes ca co vamos carregar o conjunto de dados chamado iris que vem com o R, > data(iris) Este conjunto de dados descreve em cada linha uma planta atravs de algumas das e suas biometrias, alm da espcie a que pertence. e e Uma das primeiras coisas que podemos querer saber so as dimenses dos nossos a o dados, > nrow(iris) [1] 150 > ncol(iris) [1] 5 A funo summary() fornece-nos algumas estat ca sticas descritivas bsicas, a
> summary(iris) Sepal.Length Min. :4.300 1st Qu.:5.100 Median :5.800 Mean :5.843 3rd Qu.:6.400 Max. :7.900 Species setosa :50 versicolor:50 virginica :50 Sepal.Width Min. :2.000 1st Qu.:2.800 Median :3.000 Mean :3.057 3rd Qu.:3.300 Max. :4.400 Petal.Length Min. :1.000 1st Qu.:1.600 Median :4.350 Mean :3.758 3rd Qu.:5.100 Max. :6.900 Petal.Width Min. :0.100 1st Qu.:0.300 Median :1.300 Mean :1.199 3rd Qu.:1.800 Max. :2.500
Estat sticas descritivas

Por vezes interessa-nos ter este tipo de anlise descritiva por sub-grupos dos dados. a Quando os sub-grupos so denidos por factores, podemos usar a funo by(), a ca
> by(iris[,-5],iris$Species,summary) iris$Species: setosa Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.300 Min. :2.300 Min. :1.000 Min. :0.100 1st Qu.:4.800 1st Qu.:3.200 1st Qu.:1.400 1st Qu.:0.200 Median :5.000 Median :3.400 Median :1.500 Median :0.200 Mean :5.006 Mean :3.428 Mean :1.462 Mean :0.246 3rd Qu.:5.200 3rd Qu.:3.675 3rd Qu.:1.575 3rd Qu.:0.300 Max. :5.800 Max. :4.400 Max. :1.900 Max. :0.600 -----------------------------------------------------------iris$Species: versicolor Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.900 Min. :2.000 Min. :3.00 Min. :1.000 1st Qu.:5.600 1st Qu.:2.525 1st Qu.:4.00 1st Qu.:1.200 Median :5.900 Median :2.800 Median :4.35 Median :1.300 Mean :5.936 Mean :2.770 Mean :4.26 Mean :1.326 3rd Qu.:6.300 3rd Qu.:3.000 3rd Qu.:4.60 3rd Qu.:1.500 Max. :7.000 Max. :3.400 Max. :5.10 Max. :1.800 -----------------------------------------------------------iris$Species: virginica Sepal.Length Sepal.Width Petal.Length Petal.Width Min. :4.900 Min. :2.200 Min. :4.500 Min. :1.400

Anlise por a sub-grupos

68

MANIPULACAO DE DADOS

1st Qu.:6.225 Median :6.500 Mean :6.588 3rd Qu.:6.900 Max. :7.900

1st Qu.:2.800 Median :3.000 Mean :2.974 3rd Qu.:3.175 Max. :3.800

1st Qu.:5.100 Median :5.550 Mean :5.552 3rd Qu.:5.875 Max. :6.900

1st Qu.:1.800 Median :2.000 Mean :2.026 3rd Qu.:2.300 Max. :2.500

Por vezes pretendemos unicamente ver os dados, ou parte deles. Neste tipo de tarefas, nem sempre prtico escrevermos o nome do data frame devido ` dimenso dos dados. e a a a Nestas situaes, existem algumas funes uteis como por exemplo as seguintes, co co > head(iris) Sepal.Length Sepal.Width Petal.Length Petal.Width Species 5.1 3.5 1.4 0.2 setosa 4.9 3.0 1.4 0.2 setosa 4.7 3.2 1.3 0.2 setosa 4.6 3.1 1.5 0.2 setosa 5.0 3.6 1.4 0.2 setosa 5.4 3.9 1.7 0.4 setosa

1 2 3 4 5 6

> tail(iris) Sepal.Length Sepal.Width Petal.Length Petal.Width Species 6.7 3.3 5.7 2.5 virginica 6.7 3.0 5.2 2.3 virginica 6.3 2.5 5.0 1.9 virginica 6.5 3.0 5.2 2.0 virginica 6.2 3.4 5.4 2.3 virginica 5.9 3.0 5.1 1.8 virginica

145 146 147 148 149 150

> str(iris)
`

data.frame': $ Sepal.Length: $ Sepal.Width : $ Petal.Length: $ Petal.Width : $ Species :

150 obs. of 5 variables: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

As primeiras duas funes mostram as primeiras e ultimas linhas do data frame, co enquanto que a funo str() d-nos um sumrio global do data frame. ca a a Finalmente, os esquemas de indexao que estudamos na Seco 2.6 podem ser usados ca ca para obter sub-grupos de dados, aos quais podemos aplicar alguma funo de sumarizao ca ca se desejarmos, como os seguintes exemplos ilustram, > summary(iris[iris$Petal.Length > 6, ]) Sepal.Length Min. :7.200 1st Qu.:7.400 Median :7.700 Mean :7.578 3rd Qu.:7.700 Max. :7.900 Sepal.Width Min. :2.600 1st Qu.:2.800 Median :3.000 Mean :3.144 3rd Qu.:3.600 Max. :3.800 Petal.Length Min. :6.100 1st Qu.:6.100 Median :6.400 Mean :6.433 3rd Qu.:6.700 Max. :6.900 Petal.Width Min. :1.800 1st Qu.:2.000 Median :2.100 Mean :2.122 3rd Qu.:2.300 Max. :2.500 Species setosa :0 versicolor:0 virginica :9

> summary(subset(iris, Petal.Length > 6)) Sepal.Length Min. :7.200 1st Qu.:7.400 Sepal.Width Min. :2.600 1st Qu.:2.800 Petal.Length Min. :6.100 1st Qu.:6.100 Petal.Width Min. :1.800 1st Qu.:2.000 Species setosa :0 versicolor:0

4.2

Sumarizao de dados ca

69

Median :7.700 Mean :7.578 3rd Qu.:7.700 Max. :7.900

Median :3.000 Mean :3.144 3rd Qu.:3.600 Max. :3.800

Median :6.400 Mean :6.433 3rd Qu.:6.700 Max. :6.900

Median :2.100 Mean :2.122 3rd Qu.:2.300 Max. :2.500

virginica :9

> summary(subset(iris, Petal.Length > 6, c(Petal.Width, Species))) Petal.Width Min. :1.800 1st Qu.:2.000 Median :2.100 Mean :2.122 3rd Qu.:2.300 Max. :2.500 Species setosa :0 versicolor:0 virginica :9

> summary(subset(iris, Petal.Length > 6, Sepal.Width:Petal.Width)) Sepal.Width Min. :2.600 1st Qu.:2.800 Median :3.000 Mean :3.144 3rd Qu.:3.600 Max. :3.800 Petal.Length Min. :6.100 1st Qu.:6.100 Median :6.400 Mean :6.433 3rd Qu.:6.700 Max. :6.900 Petal.Width Min. :1.800 1st Qu.:2.000 Median :2.100 Mean :2.122 3rd Qu.:2.300 Max. :2.500

Note que as duas primeiras instruoes produzem exactamente os mesmo resultados. c A segunda usa a funo subset(), que uma forma alternativa de fazermos indexao de ca e ca estruturas como os data frames, mas que pode revelar-se mais prtica em certas situaes. a co As instrues seguintes mostram mais alguns exemplos do uso desta funo. co ca Por vezes estamos interessados em produzir sumrios particulares dos dados que mea lhor se adequem `s nossas necessidades. Por exemplo, poderiamos pretender ter um a tabela que para cada coluna de um data frame nos mostrasse o seu valor mdio, o me a ximo, o m nimo, o desvio padro, a varincia e o nmero de valores desconhecidos. Uma a a u forma simples de conseguir tais efeitos atravs da criao de funes prprias que proe e ca co o duzam os resultados pretendidos. Na Seco 3.3.1 iremos ver em detalhe como criar ca funes, no entanto aqui deixamos uma ilustrao de como usar essas funes criadas co ca co para obter os sumrios que pretendemos. a > meuSumario <- function(x) { + s <- c(mean(x, na.rm = T), min(x, na.rm = T), max(x, na.rm = T), + sd(x, na.rm = T), var(x, na.rm = T), length(which(is.na(x)))) + names(s) <- c("mdia", "mn", "mx", "desvioPadr~o", "vari^ncia", e a a a + "N.desc.") + s + } > apply(iris[, 1:4], 2, meuSumario) mdia e mn mx a desvioPadr~o a vari^ncia a N.desc. Sepal.Length Sepal.Width Petal.Length Petal.Width 5.8433333 3.0573333 3.758000 1.1993333 4.3000000 2.0000000 1.000000 0.1000000 7.9000000 4.4000000 6.900000 2.5000000 0.8280661 0.4358663 1.765298 0.7622377 0.6856935 0.1899794 3.116278 0.5810063 0.0000000 0.0000000 0.000000 0.0000000

A funo apply(), que j mencionamos na Seco 3.2.3, permite-nos aplicar a todas ca a ca as colunas de um data frame uma funao qualquer, produzindo desta forma um conjunto c de resultados para cada coluna. Neste caso aplicamos a funo que criamos para obter ca as estat sticas que pretendiamos.

70

MANIPULACAO DE DADOS

4.3

Frmulas o

As frmulas so objectos da linguagem R que permitem explicitar uma forma genrica o a e de um sub-conjunto de dados. Elas so muito usadas para indicar a estrutura genrica a e de um modelo de dados que pretendemos obter com uma qualquer funo. So tambm ca a e bastante usadas para obter grcos que mostrem uma relao espec a ca ca entre um subconjunto das variveis dos nossos dados. a Uma frmula tem a estrutura genrica o e varivel ~ express~o a a em que varivel representa a varivel dependente, e express~o uma expresso a a a e a que indica de que variveis depende varivel. a a Vejamos um exemplo com os dados iris, > data(iris) > names(iris) [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"

No contexto destes dados, a frmula Sepal.Length Petal.Length + Species, o indica que pretendemos obter algo (um modelo, um grco, etc.) que relacione a varivel a a Sepal.Length com as variveis Petal.Length e Species. a As frmulas tambm podem incluir transformaes dos dados, como ilustrado nesta o e co frmula o Petal.Length ~ log(Petal.Width). As expresses a seguir ao s o mbolo ~ podem inclu r:

O sinal + signicando incluso. a O sinal - signicando excluso. a O sinal . signicando incluir todas as variveis. a O sinal * aplicado a factores representa todas as combinaes dos seus valores. co A funo I() permite usar os operadores no seu verdadeiro sentido aritmtico. ca e O sinal : gera todas as interaces com os valores de um factor. co

Vejamos alguns exemplos do uso de frmulas. Comeemos por exemplos de uso de o c frmulas no contexto da obteno de modelos. O exemplo seguinte obtm um modelo o ca e de regresso linear que relaciona a varivel Petal.Length com a varivel Sepal.Width, a a a usando os dados do conjunto de dados iris. > lm(Petal.Length ~ Sepal.Width, data = iris) Call: lm(formula = Petal.Length ~ Sepal.Width, data = iris) Coefficients: (Intercept) Sepal.Width 9.063 -1.735 Os exemplos seguintes obtm modelos do mesmo tipo que relacionam a varivel Pee a tal.Length com a todas as interaces entre Sepal.Width e os valores de Species no co caso do primeiro, enquanto o segundo exemplo faz o mesmo com todas as combinaes co poss veis entre Sepal.Width e os valores de Species. > lm(Petal.Length ~ Sepal.Width:Species, data = iris)

4.4

Visualizao de dados ca

71

Call: lm(formula = Petal.Length ~ Sepal.Width:Species, data = iris) Coefficients: (Intercept) 2.1887 Sepal.Width:Speciesversicolor 0.7489 Sepal.Width:Speciessetosa -0.2085 Sepal.Width:Speciesvirginica 1.1258

> lm(Petal.Length ~ Sepal.Width * Species, data = iris) Call: lm(formula = Petal.Length ~ Sepal.Width * Species, data = iris) Coefficients: (Intercept) 1.18292 Speciesversicolor 0.75200 Sepal.Width:Speciesversicolor 0.75797 Sepal.Width 0.08141 Speciesvirginica 2.32798 Sepal.Width:Speciesvirginica 0.60490

a Na Figura 8 podemos ver um exemplo de um grco (neste caso um boxplot) que nos d uma ideia da distribuio da varivel Petal.Width para os sub-conjuntos dos a ca a dados correspondentes a cada valor da varivel Species, o que produzido pelo seguinte a e cdigo, o > boxplot(Petal.Width ~ Species, data = iris)

1.0

1.5

2.0

2.5

0.5

q q

setosa

versicolor

virginica

Figura 8: Um grco obtido com uma frmula. a o

4.4

Visualizao de dados ca

O R tem como um dos seus pontos mais fortes a exibilidade e poder em termos de visualizao de dados. De facto, para alm de uma srie de funes de alto n ca e e co vel que produzem os grcos mais comuns neste tipo de anlises, o R possibilita ao utilizador, a a

72

MANIPULACAO DE DADOS

Sistemas de grcos a

atravs de um conjunto de funes de mais baixo n e co vel, alterar e produzir grcos que mea lhor se adequem ao seu problema. Neste documento iremos analisar alguns dos aspectos mais bsicos deste vasto assunto. Para informao mais detalhada pode ser consultado a ca o interessante livro R Graphics por Murrell (2006). Os grcos em R esto organizados em 2 tipos de sistemas de grcos: a a a 1. O sistema tradicional implementado na package graphics. 2. O sistema de grcos Trellis implementado com base na package grid e disponia bilizado na package lattice. As funes disponibilizadas em cada uma destas packages podem ser divididas em 3 co classes de funes: co

Funes de alto-n que produzem grcos completos. co vel a Funes de baixo-n que permitem adicionar elementos a grcos j desenhados. co vel a a Funes para trabalhar de forma interactiva com grcos j desenhados. co a a

Devices grcos a

Independentemente do tipo de grcos que produzimos eles vo parar a um dea a terminado device grco. Por defeito, e na maioria das situaes, esse device vai ser o a co cran. No entanto, existem situaes em que podemos crer mudar o device de sa dos e co da grcos, como por exemplo se pretedermos colocar o grco num cheiro PDF. A escolha a a do device dene no s o local onde o grco produzido, mas tambm o tipo de output. a o a e e Por exemplo, se pretendemos que um determinado grco v parar a um cheiro em a a formato PDF, podemos fazer algo do gnero, e pdf(file='exp.pdf') plot(rnorm(10)) dev.off() Se quisessemos o mesmo em formato JPEG, jpeg(file='exp.pdf') plot(rnorm(10)) dev.off() Qualquer destes (e de muitos outros) devices existentes no R, tem uma srie de pare a metros que permitem controlar o output. Em R tambm poss abrir vrios devices ao mesmo tempo, embora s um deles e e vel a o possa estar activo (para onde vo os grcos). Isto util, por exemplo, para ter vrios a a e a grcos no cran ao mesmo tempo. a e A funo windows() permite abrir mais uma janela de grcos em Windows, ca a > plot(rnorm(10) > windows() > plot(rnorm(20) O segundo grco vai surgir numa outra janela, o que permite ao utilizador ver os a dois ao mesmo tempo se quiser. Note que posteriores grcos que venhamos a realizar a vo ser desenhados na segunda janela de grcos (o device actualmente activo). a a As funes dev.cur(), dev.set(), e dev.list() so uteis para saber qual o device co a activo actualmente, mudar o device activo, e listar os devices activos.

4.4

Visualizao de dados ca

73

Histogram of iris$Petal.Width
35 Frequency 0 0.0 5 10 15 20 25 30

0.5

1.0

1.5

2.0

2.5

iris$Petal.Width

Figura 9: Um exemplo de um histograma. 4.4.1 Grcos Univariados a

stogramas

Quando pretendemos visualizar um unica varivel, em particular se ela cont a e nua, temos ao nosso dispr vrias funes de alto n o a co vel. Por exemplo, podemos obter um histograma da varivel: a > hist(iris$Petal.Width) O resultado desta instruo pode ser visto na Figura 9. ca A Figura 10) mostra uma outra variante de um histograma obtida manipulando alguns dos parmetros da funo hist(). a ca > hist(iris$Petal.Width, main = "Histograma de Petal.Width", xlab = "", + ylab = "Probabilidade", prob = T)

Histograma de Petal.Width

Probabilidade

0.0 0.0

0.2

0.4

0.6

0.8

1.0

0.5

1.0

1.5

2.0

2.5

Figura 10: Ainda outro histograma. Os grcos de caixa de bigodes (box plots) so outros grcos univariados bastante a a a usados. Podem ser obtidos em R usando a funo boxplot() da seguinte forma (ver o ca resultado na Figura 11), > boxplot(iris$Petal.Length, main = "Petal.Length") A funo barplot() pode ser usada para obter grcos de barras, conforme ilustrado ca a no seguinte exemplo (ver Figura 12), criado para nos mostrar quantas plantas existem de cada espcie dentro do subconjunto que tem P etal.W idth > 1, e
Grcos de barras a Boxplots

74

MANIPULACAO DE DADOS

Petal.Length
7

Figura 11: Um grco de caixa de bigodes. a > barplot(table(subset(iris, Petal.Width > 1)$Species))

10

20

30

40

50

setosa

versicolor

virginica

Figura 12: Um grco de barras. a

4.4.2

Grcos de 3 Variveis a a

As funes principais para obter grcos com dados que envolvem 3 variveis so: co a a a

persp() para produzir superf cies tridimensionais. countour() para produzir grcos com curvas de n representando uma supera vel f tridimensional. cie image() para produzir uma representao bidimensional de uma superf tridica cie mensional, usando cores para representar a 3 dimenso. a

Grcos a tri-dimensionais

Vejamos alguns exemplos da sua utilizao. ca > > > + + + x <- seq(-10, 10, length = 30) y <- x f <- function(x, y) { r <- sqrt(x^2 + y^2) 10 * sin(r)/r }

4.4

Visualizao de dados ca

75

> z <- outer(x, y, f) > z[is.na(z)] <- 1 > persp(x, y, z, theta = 30, phi = 30, expand = 0.5, col = "lightblue") e O resultado das instrues apresentadas acima, que pode ser visto na Figura 13, uma co representao tri-dimensional da funo 10 ca ca
sin( x2 +y 2 )

x2 +y 2

. Para isso criamos uma funo ca

(f()) que calcula o valor da referida expresso, para quaisquer valores de x e y. Depois, a usamos a funo outer() para obter os valores dessa funo para todas as combinaes ca ca co de um conjunto de valores de x e y.

Figura 13: Um grco tri-dimensional com a funo persp. a ca A Figura 14 mostra-nos um outro exemplo de utilizao da funo persp(), usando ca ca outras parametrizaes, bem como um outro conjunto de dados dispon no R. co vel > > > > > + > z <- 2 * volcano x <- 10 * (1:nrow(z)) y <- 10 * (1:ncol(z)) op <- par(bg = "slategray") persp(x, y, z, theta = 135, phi = 30, col = "green3", scale = FALSE, ltheta = -120, shade = 0.75, border = NA, box = FALSE) par(op)

Por vezes estamos interessados em obter representaes bi-dimensionais de superf co cies tri-dimensionais. Isto pode ser conseguido de vrias formas. Uma delas consiste em usar a curvas de n que possam transmitir a ideia do valor da terceira dimenso. No R tal vel a efeito pode ser obtido com a funo contour(). O cdigo seguinte mostra um exemplo ca o da sua utilizao com os dados volcano, cujo resultado pode ser visualizado na Figura 15. ca > x <- 10 * 1:nrow(volcano) > y <- 10 * 1:ncol(volcano) > contour(x, y, volcano, col = "red", lty = "solid") Uma alternativa `s curvas de n representar a terceira dimenso atravs de vrias a vel e a e a gradaes de cor. Isto mesmo pode ser obtido com a funo image() do modo seguinte, co ca podendo o resultado ser visto na Figura 16. > image(volcano)

Grcos de curva de a n vel

Grcos com n a veis de cor

76

MANIPULACAO DE DADOS

Figura 14: Um outro grco tri-dimensional com a funo persp. a ca

0 0

100

200

300

400

500

600

200

400

600

800

Figura 15: Um grco de curvas de n a vel.

4.4

Visualizao de dados ca

77

0.0 0.0

0.2

0.4

0.6

0.8

1.0

0.2

0.4

0.6

0.8

1.0

Figura 16: Um grco com gradaes de cor. a co

Por m, na Figura 17 podemos ver uma conjugao das duas ideias: as curvas de ca n e as cores: vel > > > > + > x <- 10 * (1:nrow(volcano)) y <- 10 * (1:ncol(volcano)) image(x, y, volcano, col = terrain.colors(100)) contour(x, y, volcano, levels = seq(90, 200, by = 5), add = TRUE, col = "peru") title(main = "Maunga Whau Volcano", font.main = 4)

Maunga Whau Volcano


600 100 200 300 y 400 500

200

400 x

600

800

Figura 17: Um grco com curvas de n e gradaes de cor. a vel co

78

MANIPULACAO DE DADOS

4.4.3

Grcos Multivariados a

Por vezes pretendemos obter grcos com dados referentes a mais do que uma varivel. a a funo matplot(), por exemplo, permite-nos desenhar sries de dados, guardadas numa ca e matriz em que cada coluna tem uma srie de dados. Vejamos um exemplo cujo resultado e apresentado na Figura 18, e > > > > > m <- matrix(rnorm(100), 20, 5) op <- par(mfrow = c(1, 2), mar = c(2, 3, 0, 1)) matplot(m) matplot(m, type = "l") par(op)

4 5 2 2 1 2 2 4 1 3 5 2 5 1 2 1 3 1 1 m 1 5 5 10 15 20 5 10 15 20 3 2 1 0 32 251 2 4 511 4 2 5 33 21 1 5 2 5 5 3 54 43 3 5 4 1 1 3 4 52 41 3 5 1 4 3 2 4 3 5 1 3 1 4 4 1 55 5 2 3 2 4 3 1 5 22 4 3 4 2 1 2 4 1 3 4 3 2 2 4 5 3 4
Figura 18: Grcos de vrias sries de dados. a a e Em R tambm poss e e vel encontrar diversas funes que so capazes de lidar com co a data frames formados por vrias colunas. Obviamente, este tipo de grcos, muitas vezes a a resulta em guras demasiado cheias com pouca compreensibilidade, devido ` dimenso a a dos dados. No entanto, em muitas situaes, estas so boas ferramentas de anlise visual co a a de dados. A funo pairs() provavelmente a mais comum para este tipo de dados. Ela produz ca e uma matriz simtrica de grcos bivariados, como podemos ver na Figura 19, e a
> pairs(iris[,1:4])

m
Grcos bivariados a

4.4

Visualizao de dados ca

79

2.0

3.5
qq qq q q qq q q q qq qq qq q q q q q qq qq q q qq q qq qqq q qq qq qq q q qqq q qq q qq qq qq qq q qq qq qq q qqqq q q qq q qqq q q qq qq q q q q qq qq q q q q q q qq q q qq q q q q q q q q q q qq q q q q q q q q qq qq q q q qq q qq q q q q q q q q qq q q q q q qq q q q q

0.5

2.0

Sepal.Length

2.0

q qqq qqq q q qq qqqq qq q q q q q qq q qq q q q q qqq q q qq qq qq q qq qqq qq q q q qq q q q q q q q qqq q q q qqq q q q q qq q q q q qq qq q q q q qq q q q qq q q qqq q q qq q q q q q q qq qq q q q q qqq q qq q qq q qqq q qq q qq q qqqq qqqq q qqq qq qq q q q qqqqq qqqq qqqqq q qqq q qqq qqqq qq qq q q q q q qq qqq qqq qqqq q qq qqqqq q qqq q q qq qq q q q qq qq q qq qq q q q qqq q q q qq q qqqq q qqq q qq q q q qq q q q qqqq q qqqq qq qqqq q qq q q q qq q qqq q q qq qqq q q qqq q q qqqqq qqqqq qq qqq q qqqq qq

Sepal.Width

q q q q qq q q q qq qq q qq qq qqqq q qqq qq q qq q q qqqqqq q qq q qq q qq q q qqq q qqq qq qqq qq q q qqqqq q q q qq qq q q q qqq q q

q q q qq qq q q qq q qq qq qq q q q qq q q q q q

qq q q q q qqqq qq q q qqqqqq qq qq qq q qq qq q qq qqqq qq q q qqqqq qq q q qqq qq q q q q qq qq q q qq q q qq qq qq qq q q q q qq qqq qqq q qq q qqq q q qqq q qqqqq qq qqq q q qq qqq qqq q qq q q

3.5

qqq q qq q q q qqqqq qqqqq qq qqq qq q q qq qq qq qq q q qqqq q q q qqq q q qqqqq qqqq qqqq q q q qqq q qqqqqqq q qqqqqqq qq q qqqq q

Petal.Length
qq qqq qq qqq qq qq qq q q q qqq q qqq q qq qq qq qqqq qq qq qq qq qq q q qqqq q qq q qq qq qq q qq qq q qqq qqq q qq qq qq q q qq q qqq q q qq q q q q q qq q q q qq q qq qq q q q q qq q q

qq q qqqqq q qqq qq q q qq qq q q qqq qq qqqq qq q q q q qqqqq qqq q qqqq qqq qqqq qq q qqqq qqqq qqq qq q q q qqqqqq qq qqqqqq q qq qq q qqq q q

2.0

Petal.Width

0.5

4.5

6.5

Figura 19: Uma matriz de grcos bivariados. a Tirando partido da exibilidade da programao em R poss modicar grandeca e vel mente este tipo de funes, fazendo por exemplo o R incluir histogramas de cada uma das co variveis na diagonal da matriz de grcos da Figura 19, ou mesmo substituir a parte a a superior da matriz (tirando partido dela ser simtrica), por outros grcos. Vejamos e a alguns exemplos deste tipo de modicaes. co Na Figura 20 vemos um grco do tipo pairs onde, na diagonal, acrescentamos a histogramas de cada uma das variveis, e na parte superior direita colocamos os valores a da correlao, numa fonte tanto maior quanto maior a correlao. Para isso, criamos ca ca duas funes: panel.hist() e panel.cor() que produzem esses objectivos e que so co a passadas depois em certos argumentos da funo pairs(). ca > panel.hist <- function(x, ...) { + usr <- par("usr") + on.exit(par(usr)) + par(usr = c(usr[1:2], 0, 1.5)) + h <- hist(x, plot = FALSE) + breaks <- h$breaks + nB <- length(breaks) + y <- h$counts + y <- y/max(y) + rect(breaks[-nB], 0, breaks[-1], y, col = "cyan", ...) + } > panel.cor <- function(x, y, digits = 2, prefix = "", cex.cor) { + usr <- par("usr") + on.exit(par(usr)) + par(usr = c(0, 1, 0, 1)) + r <- abs(cor(x, y))

4.5

q qqq q q qqq q q qq qq q qqq q q qqq qq qqq q q qq qq q q qqqqq q q q qqqqq q qq qqq q q qqq qqqq q qq qq qqqq qq q qq q q q qqqqq q q qqq q q q qq q qqq q qqqq qq q qq qq qq qq

qq qq qq q qqq qqq qq qqq q q q qq q qq qqqq q q qq qq q q qq q q q qq q q qqqq qq qq qq qq q qq q q qq q q qq qq q qq qq q q qq q q qqq q q qqq q q q qq q q qq q q qq q q q q q qq

6.5

80

MANIPULACAO DE DADOS

+ txt <- format(c(r, 0.123456789), digits = digits)[1] + txt <- paste(prefix, txt, sep = "") + if (missing(cex.cor)) + cex <- 0.8/strwidth(txt) + text(0.5, 0.5, txt, cex = cex * r) + } > pairs(USJudgeRatings[1:5], lower.panel = panel.smooth, upper.panel = panel.cor, + diag.panel = panel.hist, cex.labels = 2, font.labels = 2)

6.0

7.5

9.0

0.13

0.15

0.14

q q q qqq q qqq q q qq q q q qq q q q qq q q q qq q q q qq q q q q

9.0

INTG

0.96
q q qq qq q qq qq qq q qq q qq qq qq qq q q q qq q q q q

0.87
0.84

0.81
5 6 7 8 9 8.5 5.5 5.5 7.0 7.0 8.5

7.5

6.0

qq q q qqq qq q qq qq q q q qqq q q qq q q q q q q q qq qq qq q q q

DMNR

q q qq q

q q

0.81

q qqq q q qq q q q q qq qq q q q q qq q q q q q qq q q q qq q q q q q q q qq q q q qq q q qq qqqq q q q q q q q q q qq q q q q q q q q q qq q q qq q

qq qq q qqq q q q qqqq q qq qq qq qqq qqq q q qq q q q q q q q q q q qq q q qq q q qqqq q q q qq q qq q q qq q q q q q q q q q q q q q

q q q

qq qq q q qq q qq qq q qq qq qq qq qq q q q q q q q q q q q q q q

DILG

0.96
qq q q qqq q q qqq qq q q q q qq q qq qq q q qqqq q qq q q q

q q q qq qq q qq q q qqq q q q q qq qq q qqq q q q q q q q q q q q q q q

CFMG

6 7 8 9

5 6 7 8 9

Figura 20: Um grco pairs com histogramas no meio e valores da correlao no canto a ca superior direito. Um outro tipo de grcos que por vezes muito interessante uma vez que nos pera e mite comparar observaes descritas por vrias variveis cont co a a nuas, so os grcos do a a tipo stars. Estes grcos mostram cada observao de um data frame por uma espcie a ca e de estrela, com tantos raios quantas as variveis que descrevem as observaes. O tamaa co nho de um raio representa a diferena do valor nessa varivel na observao em causa c a ca relativamente ao valor mdio em todas as observaes (depois de normalizados todos os e co valores). A primeira varivel representada pelo raio na posio horizontal, ` direita. a e ca a As variveis seguintes seguem o sentido contrrio aos ponteiros de relgio. Vejamos um a a o exemplo com o conjunto de dados mtcars usando para isso a funo stars(), ca > stars(mtcars[1:10, 1:7], main = "Motor Trend Cars")

Grcos stars a

6 7 8 9

CONT
0.012

4.4

Visualizao de dados ca

81

Note que este tipo de grcos de dif visualizao quando o nmero de obsera e cil ca u vaes grande, podendo ns, nessas situaes, focar-mo-nos em sub-conjuntos mais co e o co interessantes dos dados.

Motor Trend Cars

Mazda RX4 Wag Mazda RX4 Datsun 710

Hornet 4 Drive Hornet Sportabout

Valiant

Merc 240D Duster 360 Merc 230

Merc 280

Figura 21: Um grco stars. a Finalmente, vamos ver um tipo de grcos bastante util para variveis nominais que a a so os grcos do tipo mosaic. Eles usam as reas relativas de diversos rectngulos a a a a para representar as diferenas entre as propores de casos que possuem determinados c co valores das variveis nominais em estudo. Vejamos um exemplo com o conjunto de dados a Titanic que vem com o R, > mosaicplot(Titanic, main = "Survival on the Titanic") O resultado desta chamada ` funo mosaicplot() pode ser visto na Figura 22. a ca 4.4.4 Grcos Condicionados a
Grcos a condicionados Grcos mosaic a

Por vezes pretendemos obter certo tipo de grcos para diferentes sub-grupos dos nossos a dados, de tal modo que seja fcil comparar cada sub-grupo. Por exemplo, poderiamos a querer obter um grco de caixa de bigodes da varivel Petal.Width para cada espcie de a a e planta (ver Figura 23). Em R isso fcil obter, uma vez que a prpria funo boxplot() e a o ca permite explicitar este tipo de condicionamentos usando as frmulas que estudamos na o Seco 4.3 ca
> boxplot(Petal.Width ~ Species, iris)

82

MANIPULACAO DE DADOS

Survival on the Titanic


No 1st Child Adult 2nd Child Adult Child 3rd Adult Child Crew Adult

Sex
Female Yes No

Male Yes

Class

Figura 22: Um grco mosaic. a

4.4

Visualizao de dados ca

83

1.0

1.5

2.0

2.5

0.5

q q

setosa

versicolor

virginica

Figura 23: Um grco condicionado. a

4.4.5

Interaco com Grcos ca a

Por vezes pretendemos ter alguma forma de interagir com os grcos desenhados no cran. a e O R tem algumas funes que podem ser usadas neste contexto. A funo locator(), co ca por exemplo, pode ser usada para obter as coordenadas dos pontos cliquados com o rato numa janela de grcos. Uma exemplo de uma situao em que isto pode dar jeito a ca e para interactivamente decidir a localizao da legenda de um grco. Isto pode ser feito ca a da seguinte forma:

> plot(AirPassengers) > legend(locator(1), "n.passageiros", lty = 1)

84

MANIPULACAO DE DADOS

600

AirPassengers

100

200

300

400

500

n.passageiros

1950

1952

1954 Time

1956

1958

1960

A funo legend() permite acrescentar uma legenda numas determinadas coordenaca das X-Y do grco. Na Secao 4.4.6 iremos ver esta e outras funes mais em detalhe. a c co No exemplo acima, em vez de explicitar as coordenadas X-Y onde queremos colocar a legenda, usamos a funo locator(). Ao encontrar esta funo o R vai car em modo inca ca teractivo, o que quer dizer que ca ` espera que o utilizador clique num qualquer local da a janela grca. O resultado da funo so as coordenadas X-Y do local onde o utilizador a ca a cliquar. O argumento da funo indica quantos cliques esperamos do utilizador. ca Uma outra funo interactiva a funo identify() que serve para identicar pontos ca e ca espec cos de um grco e por exemplo escrever perto os respectivos valores da varivel. a a Experimente esta funo com os seguintes exemplos: ca > plot(CO2$uptake) > identify(CO2$uptake) > plot(CO2$uptake) > identify(CO2$uptake, labels = CO2$Plant) 4.4.6 Adicionar Informao a Grcos Existentes ca a

Acrescentar novos dados

O R tem vrias funes que podem ser usadas para acrescentar diversos tipos de infora co mao a grcos j existentes. ca a a Por exemplo, a funo points() pode ser usada para acrescentar novos dados a um ca grco j desenhado: a a > plot(rnorm(10)) > points(rnorm(10), col = "red") O resultado pode ser observado na Figura 24 onde os pontos a vermelho foram acrescentados ` posteriori, atravs da chamada ` funo points(). a e a ca O R tem tambm algumas funes que podem ser usadas para acrescentar mais ale co guns elementos a grcos que j existem. Vejamos um exemplo, ainda com o mesmo a a histograma (resultado na Figura 26),

4.4

Visualizao de dados ca

85

q q q q q

rnorm(10)

q q q q q q q

1 2

6 Index

10

Figura 24: O uso da funo points. ca Por vezes os novos dados que pretendemos acrescentar devem ser desenhados como linhas. Para isso a funo lines() mais indicada, e o seguinte exemplo ilustra a sua ca e utilizao: ca > plot(rnorm(10)) > lines(rnorm(10), col = "red") O resultado pode ser observado na Figura 25.

Acrescentar linhas

0.5

1.0

0.0

rnorm(10)

q q

q q

0.5

q q

1.0

1.5

6 Index

10

Figura 25: O uso da funo lines. ca O exemplo seguinte mostra uma utilizao da funo lines() noutro contexto. ca ca > hist(iris$Petal.Width, main = "Histograma de Petal.Width", xlab = "", + ylab = "Probabilidade", prob = T)

86

MANIPULACAO DE DADOS

> lines(density(iris$Petal.Width)) > rug(jitter(iris$Petal.Width)) a ca Neste exemplo concreto, cujo resultado apresentado na Figura 26, passamos ` funo e como argumento o resultado produzido pela funo density(). Esta funo produz ca ca uma estimativa usando uma aproximao tipo kernel ` densidade da distribuio de ca a ca uma varivel cont a nua. Finalmente, usamos a funo rug() para desenhar pequenos ca traos nos valores concretos da varivel, perto do eixo onde est a escala do grco. c a a a Para evitar demasiadas sobreposies, causadas por valores muito iguais, usamos ainda co a funo jitter() que pega num vector de nmeros e causa-lhes pequenas perturbaes ca u co aleatrias. o
Histograma de Petal.Width

Probabilidade

0.0 0.0

0.2

0.4

0.6

0.8

1.0

0.5

1.0

1.5

2.0

2.5

Figura 26: Um histograma com elementos extra. Tambm relacionada com o desenho de linhas num grco j existente, est a funo e a a a ca abline(). Esta funo permite desenhar linhas horizontais, verticais, ou mesmo linhas ca inclinadas atravs da indicaao do valor de Y quando X zero e da inclinao da recta. e c e ca Vejamos exemplos destas utilizaes, cujo resultado pode ser observado na Figura 27, co > > > > > x <- rnorm(10) plot(x) abline(h = mean(x), col = "green", lty = 2) abline(v = 3, col = "blue", lty = 4) abline(-0.3, 0.5, col = "red", lty = 3)

Acrescentar texto

Em R tambm poss acrescentar texto a grcos existentes. A funo text(), por e e vel a ca exemplo, pode ser usada para acrescentar qualquer texto em determinadas coordenadas de um grco. Vejamos um exemplo, a > y <- rnorm(10) > plot(y) > text(1:10, y, ifelse(y > 0, "pos", "neg")) Neste exemplo (ver Figura 28), escrevemos o texto pos ou neg em cima de cada ponto desenhado, dependendo de o seu valor de Y ser positivo ou negativo, respectivamente. A funo mtext(), por sua vez, pode ser usada para acrescentar qualquer texto `s ca a margens de um grco. A margem a usar determinada pelo parmetro side desta a e a funo. Vejamos um exemplo cujo resultado aparece na Figura 29, ca

4.4

Visualizao de dados ca

87

1.0

0.5

0.0

q q

0.5

1.0

q q

1.5

6 Index

10

Figura 27: O uso da funo abline. ca

pos q 2

pos q 1

pos q 0 neg q neg q 1 neg q

pos q

neg q neg q neg q

6 Index

10

Figura 28: A funo text. ca

88

MANIPULACAO DE DADOS

> > > > >

plot(rnorm(10)) mtext("margem de baixo", side = 1) mtext("margem de baixo (2 linha)", side = 1, line = 1) mtext("margem esquerda", side = 2) mtext("margem direita", side = 4)

0 1 margem esquerda

q q

margem de baixo margem de baixo (2 linha) 4 6 Index

10

Figura 29: Escrever nas margens. A funo arrows(), pode ser usada para acrescentar setas a um grco. Vejamos um ca a exemplo cujo resultado aparece na Figura 30, > plot(1:6, c(10, 20, 23, 16, 18, 25), type = "l", col = "green") > arrows(2, 12, 4, 15.7, col = "red") > text(2, 12, "descida estranha!", pos = 1) A funo tem como parmetros principais as coordenadas X-Y dos pontos origem e ca a destino da seta. A funo title(), permite acrescentar t ca tulos a grcos, embora a maioria das funa ces de alto n tenha um parmetro prprio (normalmente main) onde se pode exo vel a o plicitar directamente o t tulo do grco em causa. J a funo legend() permite-nos a a ca acrescentar uma legenda ao grco. O cdigo seguinte ilustra o uso destas duas funes, a o co aparecendo o resultado na Figura 31 > > > > plot(rnorm(10), type = "l") lines(rnorm(10), col = "red", lty = 2) title("Nmeros aleatrios") u o legend("topright", c("1 srie", "2 srie"), lty = 1:2, col = 1:2) e e

Acrescentar setas

Acrescentar t tulos e legendas

Acrescentar frmulas o

A funo legend() pode receber nos dois primeiros argumentos as coordenadas X-Y ca do canto superior direito onde deve car colocada a legenda ou, em alternativa, podemos usar uma string que indique a posio relativa da legenda, como vemos no exemplo ca acima. Veja a ajuda da funo para conhecer mais alternativas. ca Finalmente, no R tambm poss acrescentar frmulas matemticas a um grco. e e vel o a a Para indicar as frmulas temos que usar uma sintaxe um pouco complexa, cuja explicao o ca sai fora do mbito deste texto. Pode fazer demo(plotmath) no prompt do R para ver a mais exemplos da sua utilizao. Entretanto vejamos um exemplo concreto, ca

margem direita

rnorm(10)

4.4

Visualizao de dados ca

89

c(10, 20, 23, 16, 18, 25)

15

20

25

descida estranha! 10 1

3 1:6

Figura 30: Desenhar setas.

Nmeros aleatrios
1 srie 2 srie

rnorm(10)

6 Index

10

Figura 31: T tulos e legendas.

90

MANIPULACAO DE DADOS

> > > > +

x <- rnorm(100) boxplot(x, boxwex = 0.5) abline(h = mean(x)) text(0.7, mean(x) + 0.5, substitute(paste(bar(x) == sum(frac(x[i], n), i == 1, n)))) O resultado pode ser observado na Figura 32

x= 0

xi

i=1 n =

Figura 32: Frmulas matemticas. o a

4.4.7

Parmetros de Grcos a a

A estrutura genrica de um grco em R pode ser descrita pela Figura 33. Assim, e a temos uma rea com o grco propriamente dito, e uma regio circundante que forma as a a a margens do grco. Ao conjunto chama-se normalmente uma gura. a

Margem de topo Margem esquerda

Area do grafico

Margem de baixo

Figura 33: A estrutura genrica dos grcos em R. e a O espao ocupado por cada um destes elementos que formam uma gura totalmente c e congurvel pela funo par(). Esta funo permite fazer o setting permanente de a ca ca vrios parmetros grcos para o device activo actual. Descrever os inmeros parmetros a a a u a

Margem direita

4.4

Visualizao de dados ca

91

que podem ser modicados com esta funo sai fora do mbito deste texto. A ajuda da ca a funo fornece uma descrio exaustiva dos mesmos. ca ca Muitos dos parmetros que podem ser modicados pela funo par(), tambm o poa ca e dem ser atravs de parmetros da maioria das funes de alto n para produzir grcos. e a co vel a Todavia, usar esta alternativa faz com que um determinado valor para o parmetro s a o seja usado no grco em causa e no em todos os grcos produzidos no device activo, a a a como acontece quando usamos a funo par(). ca Vejamos alguns dos parmetros mais comuns e que aparecem em quase todas as a funes de alto n para produzir grcos: co vel a

col - permite indicar a cor de elementos do grco. a main - permite dar um t tulo ao grco. a xlab - permite dar um t tulo ao eixo dos Xs. ylab - permite dar um t tulo ao eixo dos Ys. xlim - permite indicar um vector com 2 nmeros que sero usados como o range u a de valores no eixo dos Xs. ylim - permite indicar um vector com 2 nmeros que sero usados como o range u a de valores no eixo dos Ys. lty - permite indicar o tipo de linhas que vo ser usadas nos grcos. a a cex - permite indicar um tamanho relativo do texto usado nos grcos. a pch - os s mbolos usados para desenhar os pontos no grco. a Dividir a Janela de Grcos em Vrias Areas a a

4.4.8

H vrias maneiras de usar a rea da janela de grcos para desenhar vrios grcos ao a a a a a a mesmo tempo. Vejamos duas das formas mais comuns:

Grcos de tamanho igual. a > op <- par(mfrow = c(2, 2)) > for (i in 1:4) plot(rnorm(10), col = i, type = "l") > par(op) O parmetro mfrow permite explicitar uma diviso igual da janela de grcos em a a a x linhas e y colunas. Assim, ao colocarmos nesse parmetro o valor c(2,1) por a exemplo, iriamos dividir o device em duas linhas com uma coluna de grcos, ou a seja dois grcos. a

Grcos de diferente tamanho - a funo layout(). a ca > layout(matrix(1:4, 2, 2)) > layout.show(4) A funo layout() recebe uma matriz como parmetro principal. As dimenses da ca a o matriz denem a forma como device dividido. Assim, no exemplo anterior ele e vai ser dividido em duas linhas e duas colunas. Os valores na matriz determinam a ordem em que so usadas cada uma das reas quando se produzem grcos. A funa a a ca o layout.show() pode ser usada para exemplicar visualmente esta informao. ca O argumento desta funo o nmero de grcos que cabem no device. ca e u a O prximo exemplo um pouco mais sosticado. Ele usa a seguinte matriz como o e argumento, > matrix(1:2, 2, 2)

92

MANIPULACAO DE DADOS

0.0

rnorm(10)

rnorm(10) 2 4 6 Index 8 10

1.0

2.0

6 Index

10

0.5

rnorm(10)

0.0

rnorm(10) 2 4 6 Index 8 10

1.0

6 Index

10

Figura 34: Vrios grcos de tamanho igual. a a

Figura 35: O layout criado.

4.4

Visualizao de dados ca

93

[1,] [2,]

[,1] [,2] 1 1 2 2

O signicado desta matriz que o primeiro grco vai ocupar as duas primeiras e a a reas da matriz (toda a primeira linha), enquanto o segundo ocupa toda a segunda linha. Isto quer dizer que na realidade s vo caber 2 grcos no nosso device. o a a > layout(matrix(1:2, 2, 2), heights = c(2, 1)) > layout.show(2) O argumento heights serve para explicitar diferentes tamanhos entre as linhas da matriz que dene as reas em que dividido o device. Neste caso, e uma vez a e que a matriz tem duas linhas, os dois nmeros indicam que os grcos na primeira u a linha vo ocupar 2/3 da rea do device, enquanto que a segunda linha ocupa 1/3. a a e vel O resultado desta diviso pode ser observado na Figura 36. E tambm poss a explicitar tamanhos absolutos usando a funo lcm() conforme poder conrmar ca a na ajuda da funo layout(). E tambm poss explicitar os tamanhos usando ca e vel o parmetro widths, ou ambos. a

Figura 36: Um layout com diferentes tamanhos. O nosso exemplo nal usa a matriz, > rbind(c(1, 2), c(3, 3)) [,1] [,2] 1 2 3 3

[1,] [2,]

como argumento, o que quer dizer que vamos ter 3 grcos, sendo que o terceiro a ocupa toda a linha de baixo da matriz de reas em que dividido o device. a e > layout(rbind(c(1, 2), c(3, 3)), height = c(1, 2)) > layout.show(3) O resultado deste layout pode ser observado na Figura 37.

94

MANIPULACAO DE DADOS

Figura 37: Mais um layout com diferentes tamanhos.

REFERENCIAS

95

Referncias e
Chambers, J. (1998). Programming with Data. Springer. Dalgaard, P. (2002). Introductory Statistics with R. Springer. Murrell, P. (2006). R Graphics. Chapman & Hall/CRC. R Development Core Team (2006). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing, Vienna, Austria. ISBN 3-90005107-0. Venables, W. and Ripley, B. (2000). S Programming. Springer.

96

REFERENCIAS

Indice
a lgebra matricial, 25, 57 determinante, 25 inversa, 25 multiplicao, 25 ca transposta, 25 ambientes workspace, 53 arrays, 26 atribuio, 11, 14 ca blocos de instrues, 46 co coero de tipos, 13 ca data frames, 29 aceder `s colunas, 29 a aceder aos elementos, 29 acrescentar colunas, 30 criar, 29 nmero de colunas, 30 u nmero de linhas, 30 u preencher, 30 datas/horas, 37 discretizar, 38 extra 39 r, mostrar, 37, 39 objectos Date, 37 objectos POSIXt, 38 sequncias, 37 e debugging, 60 debug, 62 traceback, 60 undebug, 62 expresses numricas, 11 o e factores, 15, 29 criar, 15 frequncias marginais, 17 e frequncias relativas, 17 e n veis, 15 tabelar, 16 tabulao cruzada, 16 ca Funes co argumentos, 54 actuais, 55, 56 formais, 55 lazy evaluation, 56 nmero varivel, 55 u a parmetro ..., 55 a valores por defeito, 54 criar, 52 valor, 52 funes, 56 co abline, 86 apply, 50, 69 apropos, 9 argumentos, 19 array, 26 arrows, 88 as.Date, 38 as.POSIXlt, 39 attach, 30 barplot, 73 boxplot, 73, 81 break, 48 browser, 60 by, 67 c, 13, 28 cat, 45 cbind, 23, 35, 42 class, 59 colnames, 23 contour, 75 coredata, 41 cut, 38 data, 63 data.frame, 29 dbQuery, 66 debug, 62 density, 86 det, 25 detach, 30 dev.cur, 72 dev.list, 72 dev.set, 72 di, 35, 43 dim, 22 download.le, 64 edit, 30 embed, 35 end, 34, 41 factor, 15 for, 49 format, 37 getwd, 8 gl, 19 head, 68 help, 9 help.search, 9 hist, 73 identify, 84 if, 46 ifelse, 47 image, 75 install.packages, 10 97

ISOdate, 38 jitter, 86 jpeg, 72 lag, 35, 43 lapply, 51 layout, 91 layout.show, 91 legend, 84, 88 length, 13, 28 library, 10 lines, 85 locator, 83 ls, 12 margin.table, 17 matplot, 78 matrix, 22 mean, 54 median, 47 merge, 42 methods, 59 min, 50 months, 37 mosaicplot, 81 mtext, 86 na.approx, 43 na.contiguous, 43 na.locf, 43 na.omit, 36, 43 names, 21, 27 ncol, 30, 67 next, 49 nrow, 30, 67 objects, 12 outer, 75 pairs, 78 par, 90 pdf, 72 persp, 74 plot, 32 points, 84 print, 45 prop.table, 17 q, 8 quartile, 51 rapply, 44 rbind, 23 read.csv, 63 read.csv2, 63 read.delim, 63 read.delim2, 63 read.fwf, 64 read.table, 63 read.xls, 65 rep, 19 repeat, 48 return, 52

rm, 12 rnorm, 19, 48 rollmean, 44 rownames, 23 RSiteSearch, 9 rt, 19 rug, 86 sapply, 51 scan, 45, 64 seq, 18, 37, 55 setwd, 8 solve, 25 sqrt, 14 stars, 80 start, 34, 41 str, 45, 68 strptime, 39 subset, 69 summary, 67 switch, 47 Sys.Date, 37 Sys.time, 39, 50 t, 25 table, 16 tail, 68 tapply, 51 text, 86 title, 88 traceback, 60 ts, 31 undebug, 62 vector, 14 weekdays, 37 while, 48 window, 34, 42 windows, 72 zoo, 37 indexao, 13, 20 ca ndices negativos, 21 arrays, 26 data frames, 29 matrizes, 23 vectores, 20 inteiros, 21 lgicos, 20 o strings, 21 vazios, 22 instrues iterativas, 48 co listas, 27 componentes, 27 extra 27 r, contar componentes, 28 extender, 28 juntar, 28 mostrar, 27

matrizes, 22 criar, 22 indexar, ver matrizes,indexao ca nomes dimenses, 23 o NA, 13 objectos atribuio, ver atribuio ca ca denio, 11 ca listar, 12 nomes, 12 remover, 12 ver contedo, 11 u operadores lgicos, 20 o packages, 9 instalar, 10 usar, 10 R ajuda, 9 executar, 7 executar comandos, 7 executar comandos vrias linhas, 17 a gravar estado, 8 instalao, 7 ca janela de aplicao, 7 ca packages, ver packages prompt, 7 site, 7 terminar, 8 reciclagem, 15, 18, 20, 24 sries temporais e diferenas, 35, 43 c embed, 35 m, 34, 41 funes deslizantes, 43 co grcos, 32 a in cio, 34, 41 irregulares, 36 criar, 36 funes uteis, 39 co packages, 36 janela temporal, 34, 42 juntar, 35, 42 lagging, 35 regulares, 31 criar, 31 funes uteis, 33 co valores desconhecidos, 43 scoping, 53 lexical scoping, 53 sequncias, 18 e aleatrias, 19 o

descendentes, 18 factores, 19 nmeros reais, 18 u operador :, 18, 21 repetidas, 19 sistemas de equaes, 26 co strings, 13 variveis nominais, ver factores a vectores, 12 alterar elemento, 14 alterar tamanho, 14 criar, 13 dar nomes aos elementos, 21 modo, 12 operaes aritmticas, 14 co e reciclagem, ver reciclagem tamanho, 12 vazios, 14 vectorizao, 14, 25 ca

Você também pode gostar