Bioestatística com R – 4 – Correlação e Regressão

Esse é o último tutorial dessa introdução mínima a bioestatística com R. Vamos analisar correlações entre variáveis e fazer uma regressão.

Todas as tabelas usadas nos exemplos estão nessa pasta compartilhada.

Tutorial 1 – R como calculadora

Tutorial 2 – Usando e manipulando tabelas

Tutorial 3 – Inferência: teste t e ANOVA


Correlação

Pra começar, vamos importar duas tabelas novas. Uma possui dados sobre o tamanho do corpo de diferentes animais e a outra sobre longevidade de diferentes animais: bodymass.csv e longevity.csv

body.size.data = read.table("bodymass.csv", sep=";", header = T)
longevity.data = read.table("longevity.csv", sep=";", header = T)

O primeiro passo é fundir as duas tabelas, pra conseguir uma tabela que tenha animais com seus respectivos tamanhos corporais e longevidades. Pra isso, existe a função merge. Mas antes, vale olhar as tabelas, pra saber como fazer isso.

head(body.size.data)
head(longevity.data)

A função head mostra as primeiras linhas de uma tabela. O problema aqui é o seguinte: a coluna Species da tabela de tamanhos contém o nome completo da espécie. Já na outra tabela, gênero e espécie estão separados. Mas pra função merge funcionar, ela precisa de colunas de mesmo nome nas duas tabelas, que é o que ela vai usar pra comparar e mesclar os dados. Pra isso, precisamos usar mutate pra fazer com que a coluna Species da tabela de longevidade contenha o nome completo.

library(dplyr)
longevity.data = longevity.data %>%
  mutate(Species = paste(Genus, Species, sep = " "))

A função paste serve pra “colar” várias sequências de caracteres (strings) em uma só, separadas por um caractere (nesse caso, um espaço). Agora, mesclamos as tabelas numa nova:

wdata = merge(body.size.data, longevity.data, by = "Species")
summary(wdata)

O resultado tem 666 espécies, mais do que suficiente pra usarmos aqui.

Usando ggplot, podemos investigar visualmente a relação entre tamanho corporal e longevidade.

library(ggplot2)
qplot(data = wdata, x = log(Body.mass), y = Maximum.longevity..yrs.)

Note que transformamos o tamanho corporal, pra uma escala logarítmica.

E finalmente, a correlação é calculada com a função cor.

cor(x = wdata$Body.mass, y = wdata$Maximum.longevity..yrs.,
  use = "pairwise.complete.obs")
[1] 0.3290608

O argumento use serve pra indicar o que fazer com valores que não estão na tabela (por exemplo, uma espécie que esteja faltando um valor de longevidade). Valores que estejam faltando são representados por NA em R (not available). Nesse caso, a ordem é usar só as linhas (observações) que possuam o par de valores completo.

Regressão

Um passo além é fazer uma regressão linear. Saber qual a reta que melhor explica a relação entre as duas variáveis em questão.

Pra isso, temos que rodar um modelo linear. A função é lm.

modelo = lm(data = wdata, Maximum.longevity..yrs. ~ Body.mass)

O lado esquerdo do ~, na fórmula, indica a variável dependente. Do lado direito, a variável independente.

Investigando o modelo, você descobre várias coisas:

modelo
summary(modelo)

 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)     -1.3126     1.0939   -1.20    0.231    
log(Body.mass)   4.1120     0.1971   20.86   <2e-16 ***

Dá pra ver o valor de p e os coeficientes da reta, por exemplo.

Agora, um detalhe. Na verdade plotamos o logaritmo da massa corporal. Então, vamos refazer o modelo com o logaritmo:

modelo = lm(data = wdata, Maximum.longevity..yrs. ~ log(Body.mass))
modelo
summary(modelo)

E a última coisa, pra fechar com chave de ouro. Mostrar a reta de regressão num plot. Sendo uma regressão linear, é bem fácil com ggplot:

p = qplot(data = wdata, x = log(Body.mass), y = Maximum.longevity..yrs.) +
 geom_smooth(method = "lm")
p

E voilá. A função geom_smooth() faz tudo pra você: roda o modelo (especificado como lm, como usamos antes), extrai os coeficientes e plota a reta, com o intervalo de confiança sombreado.


Espero que esses quatro tutoriais tenham servido pra quebrar o gelo em relação a usar R pra fazer análises simples. Que seja o início, primeiro passo pra análises mais complexas num futuro próximo, porque seria um desperdício não continuar se aprofundando em R, dá pra fazer muito mais do que eu mostrei aqui. Isso foi mesmo só pra facilitar uma transição, um começo. :)

Bioestatística com R – 3 – Inferência: teste t e ANOVA

Nesse terceiro tutorial, o objetivo é bem simples. Comparar duas populações usando o famoso teste t de Student e depois comparar outras três populações fazendo uma análise de variância (ANOVA).

Todas as tabelas usadas nos exemplos estão nessa pasta compartilhada.

Tutorial 1 – R como calculadora

Tutorial 2 – Usando e manipulando tabelas


Teste t

Pro teste t, vamos usar a mesma tabela do tutorial anterior, o clinical trial simulado (clinicaltrial.csv).

No anterior, vimos como filtrar e quebrar a tabela pra fazer análises. Agora faremos uma análise (o teste t) pra saber se existe uma diferença de melhora entre (1) homens e mulheres, (2) tratamento e placebo e (3) tratamento e placebo, mas só nos pacientes que fazem terapia. Note que isso não é uma sugestão de como é a análise correta a ser feita nesse caso, é só uma maneira de exercitar nossas habilidades em R.

Primeiro, precisamos importar os dados e criar a coluna de melhora:

ct.data = read.table("clinicaltrial.csv", sep=";", header = T)
wdata = ct.data %>%
 select(-age) %>%
 rename(before = scale.before, after = scale.after) %>%
 mutate(effect = after - before)

Pronto. Agora, o teste t. Existe em R uma função chamada t.test, que faz (adivinha!) testes t. Um jeito de usá-la, é passar duas colunas que você quer comparar. Assim:

data1 = wdata %>% filter(gender == "male")
data2 = wdata %>% filter(gender == "female")
t.test(data1$effect, data2$effect, alternative = "two.sided")

Uma observação: o “two.sided” também pode ser “greater” or “less”, dependendo do que você quer.

De graça, sem você pedir, R já mostra um resumo do resultado do teste. E se você quiser extrair valores específicos, tipo o valor de p ou do parâmetro t? Nesse caso, você precisa armazenar o resultado do teste em uma variável, pra poder extrair valores dela depois. O resultado é uma lista com vários valores relacionados ao resultado.

resultados = t.test(data1$effect, data2$effect, alternative = "two.sided")
resultados$p.value
[1] 0.216917

resultados$conf.int[1]
[1] -0.02688129

resultados$conf.int[2]
[1] 0.1181832

Agora, a segunda questão, a diferença entre placebo e controle.

data1 = wdata %>% filter(treatment == "SSRI")
data2 = wdata %>% filter(treatment == "Placebo")
t.test(data1$effect, data2$effect, alternative = "two.sided")

Por último, a diferença entre placebo e controle, mas só para os participantes que faziam terapia. Pra isso, precisamos filtrar a tabela antes pra pegar só esses casos. O resto é igual ao exercício anterior.

wdata = wdata %>% filter(doing.therapy)
data1 = wdata %>% filter(treatment == "SSRI")
data2 = wdata %>% filter(treatment == "Placebo")
t.test(data1$effect, data2$effect, alternative = "two.sided")

 

ANOVA

Pra esses testes, usaremos uma outra tabela, simulando um experimento de cultura de células tratadas com diferente substâncias. A tabela é cellculture.csv.

Importamos a tabela:

cc.data = read.table("cellculture.csv", sep=";", header = T)

As culturas foram tratadas com a substância A, substância B ou ambas (AB), em 9 replicatas, em dias diferentes. Queremos testar se existe diferença entre os tratamentos A, B e AB (todos expressos como porcentagem de viabilidade em relação ao controle).

Assim como pro teste t, existe uma função em R pra executar análises de variância e o nome é aov.

cc.data = cc.data %>% mutate(treatment = factor(treatment))
resultados = aov(data = cc.data, viability ~ treatment)
resultados
summary(resultados)

 

Isso não diz muito caso você queira saber quais tratamentos, em particular, são diferentes do controle. Pra isso, podemos usar o teste de Tukey, com a função TukeyHSD() nos nossos resultados de análise de variância.

TukeyHSD(resultados)

 

Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = viability ~ treatment, data = cc.data)

$treatment
           diff        lwr       upr     p adj
AB-A -25.940606 -37.742373 -14.13884 0.0000350
B-A    8.572924  -3.228843  20.37469 0.1864324
B-AB  34.513530  22.711763  46.31530 0.0000004

O resultado inclui, entre outras coisas, a análise pra cada par de tratamentos. Parece que a diferença entre A e B não é tão grande quanto a diferença entre AB e A ou B em separado.

Visualizando dados

Como adendo, vamos ver como fazer gráficos simples pra mostrar esses resultados.

Como exemplo, vamos pegar o clinical trial e plotar a diferença entre tratamento e placebo. Usaremos uma outra biblioteca, chamada ggplot2, pra fazer gráficos bonitos. Primeiro passo é instalar e carregar a biblioteca:

install.packages("ggplot2")library(ggplot2)

Agora, fazer os gráficos. A função simples pra fazer gráficos se chama qplot. Veja o exemplo (e o gráfico resultante), pra se motivar a entender como funciona. Carregamos os dados antes:

ct.data = read.table("clinicaltrial.csv", sep=";", header = T)
wdata = ct.data %>%
 select(-age) %>%
 rename(before = scale.before, after = scale.after) %>%
 mutate(effect = after - before)

Plotando:

qplot(data = wdata, x = treatment, y = effect)

Isso é o básico. Você diz qual é a tabela (data) e o que o x e o y representam (que colunas da tabela). Assim já dá pra visualizar, mas é fácil deixar mais interessante.

qplot(data = wdata, x = treatment, y = effect, geom = "boxplot")

Nesse, especificamos que geom deve ser usado (no caso, pedimos um boxplot). Se você não especifica nada, ele usa pontos (como no gráfico anterior).

E se quiséssemos colorir os pontos, dependendo da pessoa fazer ou não terapia?

Basta especificar que a cor (color) vai ser de acordo com a coluna da terapia. E sim, ele faz a legenda sozinho pra você.

Agora, parece que as pessoas com e sem terapia estão mais ou menos separadas (os pontos azuis tendem a estar mais pra cima). Podemos separar os gráficos de um jeito simples, usando facets.

Os facets separam o gráfico de acordo com uma coluna: o da esquerda é pra quem não faz terapia, o da direita pra quem faz.

Uma vez que o gráfico é satisfatório, o resto é estética. Primeiro, agora vamos armazenar o gráfico numa variável (escolhi p, de plot). E no código abaixo, são alterados, respectivamente: título, nome do eixo X, nome do eixo Y e a legenda de cada gráfico. Não se preocupe tanto com a maneira de mudar cada coisa, pra entender porque teríamos que nos aprofundar mais sobre o “jeito ggplot de construir gráficos”, o que daria todo um novo conjunto de tutoriais (ou livros, como esse, do próprio criador).

Note o sinal de + no final de cada linha (pense que estamos adicionando detalhes ao plot). Note também que antes é necessário criar uma nova coluna pra servir de rótulo compreensível pra terapia/sem terapia.

wdata = wdata %>% mutate(rotulo.terapia = ifelse(doing.therapy, "Com Terapia", "Sem Terapia"))
p = qplot(data = wdata, x = treatment, y = effect, facets = ~rotulo.terapia, geom = "boxplot") +
 labs(title = "Figura 1. Efeito do tratamento com a droga", x = "Efeito", y = "Tratamento")
 
p

Viu? Agradável ao olhar. :)


E é isso. O workflow básico tá estabelecido. Importar os dados, preparar os dados, fazer análises (que podem ser qualquer outra, não necessariamente essas feitas aqui) e visualizar as conclusões.

Bioestatística com R – 2 – Usando e manipulando tabelas

Nesse segundo tutorial, o foco é em importação e exportação de dados pra arquivos, além de como fazer as manipulações mais comuns nas suas tabelas: filtrar de acordo com critérios, criar, renomear e remover colunas, extrair resumos dos dados, entre outras coisas mais.

Todas as tabelas usadas nos exemplos estão nessa pasta compartilhada.

Tutorial 1 – R como calculadora


Importando e exportando dados

Vamos começar do que é mais direto. Digamos que você tem um conjunto de dados que quer salvar num arquivo. Pra fins de armazenamento de dados nesse tutorial, vamos usar arquivos CSV (comma-separated values, de valores separados por vírgulas). Esses arquivos são arquivos texto normais, onde cada linha do arquivo vira uma linha da tabela e as colunas são separadas por vírgulas (ou qualquer outro caractere, digamos, ponto-e-vírgula).

Então, podemos criar um conjunto de dados arbitrário em R. Conjuntos de dados são armazenados em variáveis do tipo data.frame. Pra criar um, você pode usar vetores como colunas:

numeros = c(1,2,3)
letras = c("a","b","c")
uns.dados = data.frame(
 coluna1 = numeros,
 coluna2 = letras
)
uns.dados

Se tudo deu certo, apareceu uma tabelinha, de 3 linhas, com os dados, embaixo de cada coluna tem o tipo da coluna (dbl pra double, o termo para números não-inteiros, com decimais e fctr pra caracteres/strings).

Agora, pra salvar esses dados:

write.table(df, "uns dados.csv", sep = ";", row.names = F)

De novo, tudo dando certo, deve existir um arquivo chamado uns dados.csv na mesma pasta do seu arquivo R. Quem fez tudo foi a função write.table.

A primeira coisa que você passa pra função write.table é o seu data.frame. Em seguida, o nome do arquivo (pode colocar a pasta e o resto do caminho se quiser salvar em outra pasta). Depois sep indica o caractere que separa as colunas. O “normal” é usar vírgula mesmo, como diz o nome do arquivo. Mas aqui no Brasil, por exemplo, a vírgula é usada pra separar as casas decimais, o que pode confundir na hora de ler o arquivo (em inglês, usa-se o ponto, então não é problema). Por isso eu prefiro usar ponto-e-vírgula sempre que dá. O último argumento, row.names, está colocado como FALSE, só pra que R não numere as linhas (esse seria comportamento dessa função se você colocasse TRUE ou não dissesse nada).

E se quisermos agora abrir o arquivo que acabamos de salvar? A lógica diria que existe uma função inversa, read.table que lê arquivos, mais ou menos nos mesmos moldes. O argumento header diz pra função que a primeira linha da tabela é o “cabeçalho”, contendo os nomes das colunas.

dados.lidos = read.table("uns dados.csv", sep = ";", header = T)
dados.lidos

E voilá. Você diz o nome e onde está o arquivo e qual o caractere que separa colunas e pronto! Agora faremos operações sobre os dados.

Descrevendo os dados

Primeiro, a gente tem que usar o que vimos ainda agora pra obter dados mais interessantes do que esses inventados.

A tabela que usaremos pode ser baixada aqui: clinicaltrial.csv

Essa tabela tem dados inventados e simplificados sobre um clinical trial de uma droga pisquiátrica qualquer. Ele possui 6 colunas:

  • gender: masculino/feminino
  • treatment: grupo placebo ou droga ativa (SSRI – Selective Serotonin Reuptake Inhibitor – uma classe de drogas psiquiátricas)
  • age: idade
  • doing.therapy: se a pessoa está ou não fazendo terapia ao mesmo tempo
  • scale.before: severidade do transtorno antes do tratamento, medida por uma escala
  • scale.after: severidade do transtorno ao final do tratamento, medida pela mesma escala

O objetivo aqui é aprender a extrair médias e medianas, desvios e variâncias, pra diferentes subgrupos.

Tem umas coisas que precisamos saber antes. Primeiro, carregamos a tabela (lembre-se que pra funcionar, a tabela tem que estar na mesma pasta do notebook, senão você precisa dizer a pasta também, o caminho inteiro, e não só o nome do arquivo):

ct.data = read.table("clinicaltrial.csv", sep=";", header = T)
summary(ct.data)

A função summary dá um resumo da tabela, útil pra checarmos se saiu tudo direitinho. Por exemplo, são 297 mulheres e 324 homens, idades vão de 22 a 45 e o valor na escala antes do estudo varia de 4 a 10, com média 7,129.

Agora, e se quisermos armazenar a média das idades em uma variável? Pra extrair uma coluna de uma tabela, usamos o símbolo $.Porexemplo, ct.data$age te dá a lista de valores da coluna age. E R possui uma função mean() que calcula médias (e várias outras).

mean(ct.data$age)

Nada muito diferente se quisermos a mediana, o desvio padrão ou a variância.

median(ct.data$age)
sd(ct.data$age)
var(ct.data$age)

dplyr

Agora, pra complicar um pouco. E se quisermos a média de idade só pra mulheres? Pra esse tipo de tarefa, podemos proceder de alguns jeitos diferentes. Aqui, usaremos uma biblioteca chamada dplyr.

Uma biblioteca é um pedaço de código em R, um conjunto de funções e outras coisas úteis que são agrupadas pra serem usadas como um pacote: dplyr contém funções pra manipulação de data.frames, em outro momento usaremos um outro pacote pra fazer gráficos, etc. Existem muitos muitos pacotes, pra coisas bem específicas e todo tipo de análise, feitos por pessoas de todo o planeta. Esse é um dos pontos fortes de R.

Pra instalar dplyr (ou qualquer outra biblioteca):

install.packages("dplyr")

Uma vez instalado, sempre que for usar, você precisa importar a biblioteca (ignorem os avisos que vão aparecer):

library(dplyr)

O que dplyr nos dá é um operador novo e um conjunto de funções úteis. Por exemplo, as que usaremos hoje:

  • a função mutate, pra adicionar colunas;
  • a função rename, pra renomear colunas;
  • a função filter, pra selecionar só algumas linhas da tabela de acordo com critérios;
  • a função select, pra gerar uma nova tabela só com algumas colunas selecionadas;
  • a função group_by, pra separar uma tabela em subtabelas seguindo algum critério;
  • a função summarise, pra gerar medidas descritivas de conjuntos de dados (tipo média, desvio, etc);
  • o operador %>%, pra passar tabelas pras funções ou pegar o resultado de uma função e passar pra seguinte.

As descrições acima são só pra referência, veremos uma por uma agora.

Manipulando dados

Voltemos ao problema anterior: queremos a média de idade das mulheres no estudo.

Esse é um trabalho pra função filter. Veja uma maneira de usar:

mulheres = ct.data %>% 
 filter(gender == "female")
media.idade.mulheres = mean(mulheres$age)
media.idade.mulheres

[1] 33.74411

Intuitivo? Primeiro, criamos uma nova tabela, mulheres, que contém só as mulheres da tabela original. Isso é obtido com dplyr: os dados originais (ct.data) são passados (com %>%) pra função filter, que usa como critério o gênero (coluna gender) ser igual a (==) “female”. Depois é só calcular a média das idades, como antes.

Legal. Mais complicado. E se quisermos a idade média das mulheres que faziam terapia? E das que não faziam? Tente você mesmo antes de ver como fazer abaixo (basta usar os operadores lógicos que vimos antes: E, OU, NÃO)

mulheres.terapia = ct.data %>% 
 filter(gender == "female" & doing.therapy)
mulheres.nao.terapia = ct.data %>% 
 filter(gender == "female" & !doing.therapy)


mean(mulheres.terapia$age)
[1] 33.93396

mean(mulheres.nao.terapia$age)
[1] 33.63874

Ok. Agora, digamos que estamos interessados só nas escalas, não mais na idade. Então quero uma tabela nova que não tenha a coluna de idade. Pra isso, a função select é o que queremos.

wdata = ct.data %>%
 select(gender,treatment,doing.therapy,scale.before,scale.after)
wdata = ct.data %>%
 select(-age)
names(wdata)

O que aconteceu acima: pra função select, você pode especificar que colunas quer manter ou que colunas quer remover (com o sinal de menos). A função names diz que colunas existem, só pra checar se deu certo. E o nome da variável é wdata de working data, os dados de trabalho, que estão em uso nesse momento (é só um nome que eu uso sempre quando falta um nome melhor).

Agora, imagina que você não gosta dos nomes das colunas de escalas, quer mudar só pra before e after. Pra isso, a função rename existe.

wdata = ct.data %>%
  rename(before = scale.before, after = scale.after)
names(wdata)

Próxima etapa. Queremos uma coluna nova – effect -, que indique a melhora do paciente no período, medido pela escala, ou seja, o valor da escala depois menos o valor da escala antes. A função mutate faz isso (o nome é porque ela muda, transforma a forma da tabela):

wdata = wdata %>%
 mutate(effect = after - before)

Agora dá pra mostrar uma coisa que deixa dplyr muito mais divertida. Você pode encadear várias funções. O que fizemos em três partes acima, pode ser feito de uma vez só:

wdata = ct.data %>%
 select(-age) %>%
 rename(before = scale.before, after = scale.after) %>%
 mutate(effect = after - before)

O código acima é equivalente ao que fizemos antes.

Agora a gente tem a tabela nova, podemos voltar a extrair médias (ou qualquer outra medida), como antes. Por exemplo, qual a melhora média das melhora média das mulheres que fazem terapia ou tinham a escala >= 8 antes do estudo?

subdata = wdata %>%
 filter(gender == "female" & (doing.therapy | before >= 8))
mean(subdata$effect)

Ótimo. Última coisa. Todos essas médias que calculamos pra subgrupos específicos podem ser feitas de um jeito mais interessante, usando as funções group_by e summarise. A ideia é quebrar a tabela em grupos de acordo com algumas colunas e calcular alguma coisa pra cada grupo, devolvendo os resultados já sumarizados numa tabela nova.

Exemplo. Digamos que queremos a média da melhora pra cada sexo.

medias = wdata %>%
  group_by(gender) %>%
  summarise(media = mean(effect))
medias

O resultado é uma tabela nova, que contém uma coluna pro sexo e outra pro resultado da média, que criamos na função.

E se quisermos, além de separar por sexo, saber também as médias pra grupos placebo/tratamento ativo? E se quisermos saber também o desvio padrão, além da média?

medias = wdata %>%
  group_by(gender, treatment) %>%
  summarise(media = mean(effect), desvio = sd(effect))
medias

Pronto. Nova tabela, com os resultados pra cada grupo.


É isso. Vimos como importar tabelas, usamos e abusamos de dplyr pra fazer o que quiser com os dados pra prepará-los pra análise (aqui só calculamos médias, mas vamos fazer algo mais sofisticado em breve).

Bioestatística com R – 1 – R como Calculadora

        Nesse primeiro tutorial, pra se acostumar com R e com o RStudio, a ideia é fazer contas e operações básicas. Nada de estatística por enquanto. Um passinho de cada vez (esse texto assume que você tem R e RStudio instalados e funcionando no seu sistema … se não for o caso, veja aqui como instalar).

Notebooks

Primeira coisa é abrir o RStudio e criar um notebook (File > New File > R Notebook).

Notebooks são arquivos em que você pode misturar texto formatado e de exposição com código em R, executável. É ideal pra registrar as suas análises de um modo reprodutível. Você pode criar explicações entre os trechos de código, assim o resultado é o código funcional e já documentado, ótimo pra relatar a análise pra outras pessoas (e pra fazer tutoriais).

Pronto, notebook criado. Ele já contém algum texto, explicando o básico de como usar um notebook. O que você precisa saber agora é que qualquer código tem que estar dentro de um bloco de código. Pra inserir um bloco de código, o atalho é Ctrl + Alt + I.

Apague o conteúdo que já veio no arquivo – exceto as 4 primeiras linhas, que especificam o título e o output. Mude o título como preferir (lembre que ele deve estar entre aspas).

R como Calculadora

Agora crie o primeiro bloco de código com o atalho (Ctrl + Alt + I). Digite o código abaixo no bloco de código criado.

# Variável a
a = 5
a

Ele deve mostrar [1] 5. O que essas duas linhas de código fizeram?

a = 5

Cria uma variável a e armazena o valor 5 nela. Uma observação importante: o símbolo de igual = e a setinha pra esquerda <- são equivalentes em R. Significam algo como “armazene a coisa à direita na coisa à esquerda”.

a

Isso faz com que o R te mostre o valor de a, que no caso é 5, porque fizemos isso na linha de cima.

# Variável a

Essa linha não faz nada. Como ela começa por #, ela é um comentário. Comentários (qualquer linha iniciada por #) são ignorados pelo R, só servem pra nós, humanos. Comentar o seu código de maneira informativa é um excelente hábito pra um programador. Primeiro, pra ajudar outras pessoas que venham a ler e tentar entender o seu código. Segundo, pra você mesmo se entender … não importa o quão claro e auto-explicativo seja o seu código, se você ficar dois dias sem vê-lo você vai esquecer o que estava pensando na hora.

Ok. Então você sabe como criar variáveis. Agora, façamos operações com elas.

# Operações
b = 3
c = a + b
c

Bom, tente adivinhar o que isso vai mostrar.

A resposta é 8. Coisas importantes aqui: (1) R não esquece facilmente. O valor de a que atribuímos antes ainda está lá. (2) Operações funcionam como se imaginaria. As quatro básicas são +, -, * e /. (3) Experimente. Veja os exemplos abaixo.

# Operações básicas
a * 5
[1] 25

b + 10
[1] 13

c / 2
[1] 4

c / 3
[1] 2.666667

2 * (a + b + c - 1)
[1] 30

# Potência
a ^ 2 # 5 ao quadrado
[1] 25

R não se limita a operações aritméticas básicas, é claro. Você também pode aplicar funções, várias já existem em R sem você precisar fazer nada.

cos(360)
[1] -0.2836911

cos(2*pi)
[1] 1

tan(pi/4)
[1] 1

log(10)
[1] 2.302585

log10(10)
[1] 1

Note que: (1) cosseno de 360 não é 1 … Por que? R assume que você está dizendo ângulos em radianos, não em graus. (2) Teste calcular o seno de pi radianos (180º) ou a tangente de pi/2 radianos (90º). Tente entender o que significa o resultado. (3) A função log() usa como base a constante de Euler (e). Pra calclular com base 10, exsite outra função: log10().

Juros compostos

Podemos tentar fazer coisas mais sofisticadas agora. Digamos que você tem um problema clássico de livro-texto, sobre juros compostos.

Você recebeu R$ 10.000,00 e investiu num fundo com rendimento de 5% ao ano, por 10 anos. Qual a soma total no final dos 10 anos?

inicial = 10000 # R$ 10.000,00
juros = 5 / 100 # 5%
tempo = 10 # 10 anos
final = inicial * (1 + juros) ^ tempo
final

[1] 16288.95

E se for por 20 anos? E se começar com metade do dinheiro? E se os juros triplicarem? A graça é que agora basta mudar uma linha do código acima pra chegar no novo resultado.

Outros tipos de variáveis

Além de números, variáveis em R também podem armazenar caracteres e palavras (além de objetos mais complexos, como tabelas e dados … mas fica pra depois). Esses caracteres, do tipo string, são sempre colocados entre aspas:

palavra = "tutorial"
palavra

[1] "tutorial"

Outro tipo importante é o tipo lógico. Variáveis desse tipo só podem ter dois valores: TRUE ou FALSE (também pode ser T e F). E eles tem as próprias operações. Por exemplo, imagine duas variáveis:

         chuva: que diz se está chovendo

         guardachuva: se eu tenho um guarda-chuva molhado: diz se eu vou ficar molhado

Eu só fico molhado se estiver chovendo E se eu NÃO tiver guarda-chuva. Ou, em outras palavras, eu fico seco (NÃO molhado) se NÃO estiver chovendo OU se eu tiver guarda-chuva.

Agora, em R, o símbolo & representa E, o símbolo | representa OU e o símbolo ! representa NÃO.

Expresso em R, isso fica assim:

chuva = TRUE
guardachuva = FALSE
molhado = chuva & !guardachuva
seco = !chuva | guardachuva
molhado

[1] TRUE

Teste mudar os valores de chuva e guardachuva pra ver se ficamos molhados ou secos.

Vetores

Uma última coisa, pra começarmos a entender a graça de R.

Além de variáveis que armazenam um único valor (seja ele um valor numérico, string/caracteres ou lógico ou qualquer coisa), também existem variáveis que armazenam conjuntos de valores. Existem vários tipos de “conjuntos”, mas por enquanto falaremos só dos vetores, que armazenam vários objetos do mesmo tipo (qualquer tipo, desde que todos do mesmo).

Vetores são criados com a função c() (c de combine). Exemplos:

v = c(1,2,3)
w = c(a,b,s)
sudeste = c("RJ","SP","ES","MG")
logicos = c(TRUE,FALSE,FALSE,TRUE,FALSE)

Bem legal e tal … mas e daí? E daí que você pode fazer operações em vetores. Qualquer coisa que você faz em um objeto único, isolado, você pode fazer em vetores. R entende, em geral, que você quer fazer aquilo com cada um dos elementos do vetor.

Por exemplo. Digamos que eu tenho vários números que eu quero elevar ao quadrado. Podemos fazer como antes:

n1 = 3
n2 = 20
n3 = 5

n1 ^ 2
n2 ^ 2
n3 ^ 2

[1] 9
[2] 400
[3] 25

Legal. E usando um vetor?

n = c(3,20,5)
n ^ 2

[1] 9 400 25

Problema: na minha pequena empresa eu tenho 3 funcionários, que ganham R$ 2000, R$ 1500 e R$ 1200. Quero dar um aumento de 10% pra cada um. Quanto vou pagar de salário com esse aumento?

salarios = c(2000,1500,1200)
salarios.com.aumento = salarios * 1.1
salarios.com.aumento

[1] 2200 1650 1320

Temos os salários pós-aumento. Mas e se eu quiser a soma deles? Bom, como são só três, você poderia fazer de cabeça ou no papel. Mas, a proposta aqui é exatamente deixar o R fazer isso por você. Convenientemente, existe uma função que soma todos os valores de um vetor, o nome é sum(vetor).

(PARÊNTESES SOBRE FUNÇÕES: funções recebem alguma informação sua e devolvem outra. A informação recebida é o conjunto de argumentos da função, que vem entre aprênteses depois do nome. É exatamente como no seno e cosseno ou log. A função sin(angulo) recebe um número, que ela interpreta como um ângulo em radianos e retorna o valor do seno desse ângulo. Ela recebe um número e retorna um número. A função sum(vetor) é um pouco diferente. Ela recebe um vetor de números e retorna um número (a soma dos números contidos no vetor). E existem inúmeras outras funções muito mais complicadas que essas e você pode criar as suas próprias funções também! Em outro momento …)

Então, parênteses fechado, você pode saber o total rapidamente:

total = sum(salarios.com.aumento)
total

[1] 5170

E a diferença entre o gasto antes e depois do aumento?

diferenca = sum(salarios.com.aumento) - sum(salarios)
diferenca

[1] 470

Última coisa. Imagina que você quer saber quantos dos funcionários ganharão mais do que dois salários mínimos após o aumento.

salario.minimo = 937
ganham.mais = salarios.com.aumento > salario.minimo * 2
ganham.mais
[1] TRUE FALSE FALSE

O resultado é TRUE, FALSE, FALSE. Quer dizer que R já fez as comparações, uma por uma, e reportou. E só um dos funcionários (o primeiro) ganhará mais do que dois salários mínimos.


Espero que isso dê uma amostra do que dá pra fazer com R. Especialmente esse final, a naturalidade com que R faz operações com vetores, é importante pra R ser útil e divertido.