Escolar Documentos
Profissional Documentos
Cultura Documentos
Gonçalo Ferraz
Introdução
Agora, tal como todas as caras têm olhos, nariz e boca, existem algumas
características recorrentes em qualquer interface do R. O seu ambiente de
trabalho no R terá sempre, no mínimo, duas coisas: uma janela de comando e
uma janela de script. A diferença mais evidente entre as duas é que a janela de
comando sempre tem uma linha de comando com um cursor piscando, enquanto
a janela do script é só um espaço em branco onde você pode escrever. Quando
você escreve alguma coisa na linha de comando e dá ‘enter’, o R dá uma resposta
para você; quando você escreve alguma coisa na janela do script e dá ‘enter’, você
1
pula para a próxima linha. Na janela de comando você está em contato direto
com o R. Já na janela do script, você escreve comandos e outras anotações que
pode ou não enviar mais tarde para o R. Mas note bem: até você decidir enviar
um comando para o R, o conteúdo da janela do script é só seu, ele não é parte de
um diálogo com o programa. Então, metaforicamente, quando você tem alguma
coisa para dizer para o R, escrever essa coisa na janela de comando é como falar
diretamente com o programa. Em contrapartida, escrever na janela do script é
como escrever uma mensagem que você guarda para entregar depois. Cultive o
habito de comunicar diretamente com o programa na janela de comando. Isso vai
permitir você resolver pequenas dúvidas com mais rapidez e produzir scripts
mais limpos. Se quiser recuperar comandos que você deu no R durante uma
sessão de trabalho, é só carregar na ‘setinha pra cima’ e o R vai mostrando para
você todos os comandos anteriores.
Aquilo que você escreve num script, no entanto, têm uma particularidade muito
especial: você pode selecionar qual parte do script o R vai ler. Qual é a vantagem?
É que você vai poder usar duas linguagens ao mesmo tempo, uma que o R
entende e outra, a sua linguagem, que o R não entende, mas que ajuda você a
entender o que escreveu na linguagem dele. Então, quando você escreve na
janela de comando precisa sempre usar a linguagem de programação que o R
entende. Já quando escreve no script (literalmente, um ‘roteiro’) você tem a
liberdade de escrever na linguagem do R ou em qualquer outra linguagem do seu
agrado, que para efeitos práticos podemos chamar de ‘vernáculo’. Como evitar
confusão entre as duas linguagens? Simples, a própria linguagem do R tem um
sinal que ajuda a estabelecer a diferença. Quando você escrever no seu script
algum comentário em vernáculo para ajudar a entender o que você escreveu na
língua do R, é só colocar no início da linha um sinal de jogo da velha ‘#’ e feito! O
R entende que tudo o que está para a frente do sinal é comentário e não código de
R. Comente generosamente os seus scripts, para que no futuro você e outras
pessoas possam entender a intenção e a metodologia do seu código.
Culinária e Programação
2
pasta quantas vezes quisermos através do comando setwd(), que significa ‘set
working directory’. Para saber qual pasta está definida em qualquer momento
como pasta de trabalho, use o comando getwd(). Tudo o que gravamos na pasta
de trabalho permanece gravado, mesmo depois de encerrar o R ou de desligar o
computador.
> x <- 7
> save.image(file=”Millor.RData”)
3
Millor.RData muito frequentemente, mas o nome serve para ilustrar que você
pode chamar o artigo do que você quiser. Na próxima sessão de trabalho do R, se
você quiser trazer para a área de trabalho o conteúdo de Millor.RData, basta
carregar o conteúdo com o comando:
> load(”Millor.RData”)
Como resultado, aparecerão na sua área de trabalho todos os objetos que foram
gravados anteriormente. Note aqui uma diferença de terminologia importante: a
gente ‘grava’ um script e ‘grava’ um arquivo RData com objetos do R na pasta de
trabalho. No entanto, a gente ‘carrega’ (tradução de load, em inglês) o conteúdo
de um arquivo RData para a área de trabalho. Tudo o que a gente traz para a área
de trabalho é ‘carregado’, tudo o que a gente salva na pasta é ‘gravado’. Se em
algum momento você precisar limpar a sua área de trabalho, pode fazê-lo com o
comando:
> rm(list=ls())
Vamos levar a analogia da culinária um pouco mais adiante e olhar para o script
de uma função como uma receita de cozinha. Mas primeiro, é bom clarificar a
diferença entre um comando e uma função. Vamos operar com a seguinte
distinção prática: um comando é a uma linha de instruções passadas para o R e
uma função é uma sequência especial de comandos. O que é significa uma ‘linha’?
Uma ‘linha’ é qualquer sequência de instruções em linguagem R que retorna um
4
resultado (diferente de uma mensagem de erro) após o usuário apertar a tecla
‘enter’. Por exemplo, a linha:
>3+
Ou seja, não recebo um resultado, o programa fica à espera que eu digite algo
mais para completar a instrução de somar os valores de dois números. Já a linha:
>3+4
[1] 7
E porquê o número ‘1’ entre colchetes? O que aconteceu é que a gente deu um
comando de soma para o R, mas não especificou o que o R deve fazer com o
resultado. Sendo assim, o R executa o comando e apresenta uma descrição visual
do resultado para você na janela de comando. O ‘1’ entre colchetes significa algo
como “Ó aqui ó, esse comando resultou em um vetor numérico de comprimento
igual a 1 cujo primeiro (e único) elemento tem o valor 7. Como você não me disse
o que fazer com o resultado eu vou só jogá-lo aqui na janela de comando, não vou
nem guardar na área de trabalho. Beleza?” (e sim, o R usa sufixos hifenizados no
final das palavras!) Parece que o R ficou um tanto incomodado por a gente não
ter dito o que ele deveria fazer com o resultado. Como contornar a situação? Uma
possibilidade é dar o comando na forma:
> x <- 3 + 4
>
Mas o silêncio é bom sinal. Aconteceu tudo o que tinha de acontecer. Dessa vez o
que nós dissemos para o R foi mais do que ‘some 3 com 4’. O comando agora foi
‘crie o objeto de nome ‘x’ e coloque lá dentro o resultado da soma de 3 com 4’. Foi
isso que aconteceu? Claro que sim. Experimente pedir a lista dos objetos que
estão na área de trabalho:
> ls()
[1] "x"
5
Isso significa: ‘existe um objeto de nome ‘x’ dentro da sua área de trabalho’.
Agora, se você digitar o nome do objeto:
>x
Grave o seu script (na pasta de trabalho) e em seguida execute os comandos que
você escreveu nele. A combinação de teclas que faz executar comandos do script
varia de GUI para GUI, você precisa procurar o que se aplica ao seu caso,
geralmente ctrl-enter ou espaço-enter. Lembre só que existem combinações de
teclas para executar só um comando de cada vez ou um conjunto de comandos
selecionados previamente. Após executar estes comandos, veja os objetos que
estão na sua área de trabalho:
> ls()
[1] "s" "qs"
Como era de esperar, o conteúdo da área de trabalho são os dois objetos que
você acabou de criar: s, contendo a soma de 3 com 4 e qs, contendo o quadrado
dessa soma. Muitas pessoas usam o R somente como você acabou de usar. Para
qualquer tarefa executável no R—mais ou menos complicada que obter o
quadrado da soma de dois números—vai existir uma sequência de comandos
que resolve o problema. Porque não ficar só por aí? Porque você pode tirar muito
mais partido do mesmo trabalho de programação se organizar os comandos de
forma a que eles possam ser usados de uma forma genérica, repetidamente, para
execuções diferentes de tarefas semelhantes à tarefa específica que você quer
6
executar. Mais concretamente, no exemplo acima você calculou o quadrado da
soma de 3 com 4, mas com o mesmo esforço você poderia escrever uma função
que retorna o quadrado da soma de quaisquer dois números. Vamos voltar à
janela do script para fazer isso mesmo.
Antes de executar qualquer comando, vamos dar uma olhada no código para ver
o que há de especial nessa sequência. Aparecem aqui quatro elementos que se
repetem em todas as funções:
1) Primeiro, damos um nome à função atribuindo ao objeto ‘qsoma’ o valor
de função. A atribuição é expressada pelo pedaço de código ‘qsoma <-
function’. Na analogia culinária, essa parte do código indica que a palavra à
esquerda da seta de atribuição representa uma receita de cozinha.
2) O segundo elemento é a especificação dos argumentos da função,
‘function(a,b)’, ou seja, dos valores de entrada (ou ingredientes da receita)
que serão transformados para dar origem a um produto final. Neste caso,
os argumentos da função são ‘a’ e ‘b’ , mas eles poderiam ser qualquer
lista de objetos.
3) O terceiro elemento, que aparece nas várias linhas escritas entre chaves, é
o código da função propriamente dito. O código obviamente varia entre
funções, assim como os detalhes da preparação de um prato variam entre
receitas. Mas esse código sempre aparece entre chaves e sempre indica o
que deve ser feito como os argumentos identificados entre parentes na
primeira linha.
4) Finalmente, o último elemento essencial é a especificação d o resultado
final que a função vai retornar para o usuário. Essa especificação é feita
pelo código ‘return(qs)’. Neste caso, a função retorna o valor de ‘qs’ mas o
valor retornado pode ser qualquer coisa, ou lista de coisas, produzida nos
comandos anteriores, dentro das chaves.
7
Figura 1. Uma função do R é como uma máquina de fazer linguiça. Os argumentos são a matéria prima e o
resultado final é a linguiça. A função é como uma máquina que pode ser usada repetidamente com matérias
primas do mesmo tipo mas variáveis. No exemplo da figura, a máquina só funciona se usarmos um porco,
mas o porco pode ser cinza ou rosa, baixo ou alto, gordo ou magro. Como na analogia com a receita de
cozinha, a função pode ser usada muitas vezes para executar os mesmos comandos com argumentos e com
resultados variáveis, mas sempre do mesmo tipo.
Agora vamos testar a função e você vai já ver outra diferença importante entre
uma função e uma lista de comandos. É a seguinte: para testar uma lista de
comandos gravados no seu script, tudo o que você precisa fazer é colocar o
cursor na linha correspondente a cada comando e ir executando. Simples assim.
Quando você está em dúvida sobre o funcionamento dos comandos é bom ir
checando quais foram os objetos que foram aparecendo na área de trabalho e o
seu conteúdo. Mas o processo de testar os comandos para ver se eles estão
cumprindo corretamente a sua intenção é tão simples como executar cada
comando e ir olhando os resultados. Com as funções é diferente, porque a
sequência de comandos ‘especial’ que você está usando vem envolta numa
‘casca’. Função tem casca?? Repare bem. Toda a função vem na forma:
8
Há duas maneiras complementares de testar o código de uma função. A primeira
é a que se designa em inglês como ‘debugging’ ou depuração. A depuração de
código é o nível de teste mais detalhado e deve ser o primeiro a ser usado. Ela
consiste em testar os comandos que estão dentro da casca da função. Para fazer
isso você precisa colocar na área de trabalho objetos com os mesmos nomes que
os argumentos da função (no caso ‘a’ e ‘b’). Uma vez criados esses objetos, você
pula para dentro da chave sem dar o comando da casca e testa os comandos um
por um, checando após cada comando se obteve ou não obteve o resultado
pretendido.
> ls()
[1] "qsoma"
indicando que o único objeto na sua área de trabalho é a função soma. Agora
estamos prontos para testar a execução da função. Vamos ver se ela calcula
corretamente o quadrado da soma de 2 com 3, que deveria ser 25. Para isso,
digite o comando:
> qsoma(a=2,b=3)
[1] 25
Agora vamos olhar um detalhe que vai deixar mais claro porque é que tem
atividades do R que acontecem fora do alcance da área de trabalho, na ‘cozinha’
do computador. Volte à janela de comando e peça novamente o conteúdo da área
9
de trabalho. Tem lá os objetos s e qs que apareceram durante o depuramento do
código? Nada. Eles não estão lá! Porquê? Porque eles foram criados na ‘cozinha’,
fora do seu alcance, sem a necessidade de colocar objetos dentro da sua área de
trabalho. Para entender o alcance dessa praticidade, pense que, sempre que você
coloca uma sequência de comandos dentro de uma chave, você está mandando o
computador executar uma tarefa na cozinha, fora do alcance da sua área de
trabalho. A vantagem é rapidez e facilidade de organização, que não são pouca
coisa.
Você deve ter notado que até aqui falámos de ‘tipos’ de argumentos e ‘tipos’ de
resultados de uma forma um pouco ambígua. Vamos clarificar o que são esses
‘tipos’. Tudo o que você encontra dentro da sua área de trabalho são objetos. E o
interessante do R é que você pode usar uma enorme variedade de objetos. Para
saber que tipo de objeto você tem em mãos você deve usar o comando class, que
busca a classe do objeto em causa. Por exemplo, o objeto qsoma que está na sua
área de trabalho é da classe função, portanto, se você der o comando:
> class(qsoma)
a resposta será:
[1] "function"
10
Para além da classe função existem muitas outras, pelo menos 24 listadas na
página do CRAN1. Mas também mais, porque um usuário, em caso de
necessidade, pode criar a sua própria classe de objeto. Citando só alguns
exemplos: existem objetos numéricos da classe integer, que são números
inteiros; existem objetos numéricos da classe double, que são números reais;
existem objetos que contém matrizes, da classe matrix; e existem objetos de
texto, da classe character. É importante estar sempre ciente da classe dos objetos
que você usa porque as operações executadas pelas funções só são válidas com
determinados tipos de objeto. Por exemplo, você não pode somar duas palavras e
não deve tratar matrizes como se elas fossem escalares. Muitos erros que
aparecem durante o processo de depuração se devem a confusões de classe de
objeto, em que um objeto da classe errada é passado para uma função como um
argumento que deveria ser de outra classe. À medida que for se familiarizando
com o R você vai se apercebendo da variedade e utilidade das múltiplas classes
de objeto.
Para encerrar este texto introdutório vamos combinar algumas regras básicas de
‘culinária’ que a gente deve usar no R e que vão facilitar o seu trabalho e o
trabalho dos monitores que vão corrigir o seu código. Pense nestas regras como
medidas básicas de higiene, como limpar a bancada, não pegar nas facas pela
lamina, ou separar o lixo orgânico do lixo reciclável. São três medidas principais
que você precisa tomar:
1 https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Objects
11
script confunde os monitores e confundirá você no futuro, quando você
precisar usar a código.
3) Finalmente, tome cuidado com a indentação das chaves. Cada vez que
você abre chave num script você está mandando o computador operar em
uma outra esfera, em que os objetos criados não vão mais aparecer na
área de trabalho. Na hora de depurar código é absolutamente essencial
que você tenha facilidade em se localizar relativamente às chaves. Para
isso, usamos a convenção de mudar para a próxima linha após a abertura
de uma chave e começar a escrever quatro espaços mais à frente do que o
início da linha em que a chave foi aberta. Na hora de fechar a chave,
escrevemos a chave numa linha só para ela e alinhamos a dita com o início
da linha onde a chave abriu.
Diferentes pessoas têm diferentes estilos de edição de código, mas para o nosso
trabalho neste curso, tudo será mais fácil se você atender cuidadosamente a
esses três cuidados básicos de rotina.
Bom trabalho!
12