# [Minicurso 2025] 04. Introdução ao R (e RStudio) ###### tags: `Minicurso25` ![](https://i.imgur.com/8JyxjMU.png =500x) [TOC] ## 1. Básicos da programação em R ### Acesso ao RStudio server: 1. Acessar: http://200.145.102.175:8787/ 2. Logar com suas credenciais de `login` e `senha`. ### Conhecendo a interface ***1. Script:*** Local onde escrevemos o código (perene); ***2. Console:*** Local onde escrevemos o código (temporário) e observamos os resultaydos; ***3. Ambiente/Histórico:*** Variaveis/Objetos salvos; Histórico de códigos rodados; ***4. Arquivos/Plots/Pacotes/Ajuda*** ![](https://i.imgur.com/8W8Zsjb.png) ### Teclas de Atalho | Atalho | Função | |--------|--------| | `CTRL` + `ENTER` | Executa linha atual ou seleção | | `ALT` + `-` | Adiciona o operador `<-` | | `CTRL` + `SHIFT` + `R` | Adiciona uma nova seção de código | | `CTRL` + `SHIFT` + `M` | Adiciona o operador `%>%` | | `CTRL` + `L` | Limpa o terminal do R | ### Operadores Caracteres especiais capazes de realizar funções básicas. - **Operadores matemáticos:** Permite realizar operações básicas de forma direta. Como uma calculadora ```r= # Operadores matemáticos: 2 + 3 2 * 3 2 - 3 2 / 3 2 ^ 3 ``` - **Operadores lógicos:** Permite comparar valores e expressões, retorna valores boleanos: Verdadeiro (*TRUE; T*) ou Falso (*FALSE; F*). ```r= # Operadores lógicos: 2 == 3 # Igualdade 2 != 3 # Desigualdade 2 <= 3 # Menor (<); Menor ou igual (<=) 2 >= 3 # Maior (>); Maior ou igual (>=) 2 < 3 & 3 > 5 # & = E; Só TRUE quando ambos são TRUE 2 < 3 | 3 > 5 # | = OU; É TRUE quando ao menos um é TRUE ``` - **Operadores de atribuição:** Permite atribuir valores a um objeto. São válidos os símbolos '<-' e '='. ```r= # Operadores de atribuição: a <- 3 # Cria um objeto 'a' de valor 3 a # Visualiza o objeto 'a' b = 2 b a + b # Operações válidas para o valor interno serão executadas normalmente. a - b a == b ``` ### Vetores Conjunto de elementos de um mesmo **tipo** (numérico, textual, lógicos...). - **Criação de vetores:** ```r= # Criação de vetores: # Criando vetores com a função 'c()' (Concatenar). v1 <- c(2, 6, 30, 193) # Vetor numérico (Numeric) v1 v2 <- c("a", "z", "lucas", "e. coli") # Vetor de texto (Character) v2 v3 <- c(TRUE, FALSE, TRUE) # Vetor lógico (Logical) v3 # Criando vetores de outras formas: v <- 1:5 # Sequência de 1 a 5, o mesmo que c(1, 2, 3, 4, 5) v v <- rep(1, 7) # Função rep(); Repetirá 1, 7 vezes v v <- rep("a", 7) # Também funciona com texto v v <- seq(10, 20, 2) # Função seq(); Sequência de 10 a 20, pulando de 2 em 2. v ``` - **Operação com vetores** ```r= # Operação com vetores (vx <- 1:5) (vy <- rep(1, 5)) # Operações podem ser feita entre os elementos, de forma pareada, quanto possuirem o mesmo tamanho: length(vx) # Função length() mede o tamanho de um objeto length(vy) vx + vy vx + rep(1, 6) # Erro vx > vy # Checa cada elemento de 'vx' contra cada elemento de 'vy' (na mesma posição) # Ou para cada elemento: vx * 2 # Multiplica cada elemento por 2 vx > 2 # Todos contra 2 ``` - **Elementos de vetores** ```r= # Elementos de vetores vl <- letters # Objeto especial, contém alfabeto minúsculo vl vl[20] # 20º elemento vl[c(15, 9)] # 15º e 9º elemento vl[1:5] # Série de elementos do 1º ao 5º vn <- 1:10 vn vn[c(T, T, F, F, T, T, F, F, T, T)] # Seleção lógica; Exibe T vn[vn > 5] # Maiores que 5 vn[(vn %% 2) == 0] # Apenas pares vn[(vn %% 2) != 0] # Apenas ímpares ``` ### Matrizes e Data Frames - **Matriz**: Vetores com duas dimensões (linhas/*rows* e colunas/*columns*). **Mesmo tipo!** ```r= # Matrizes # Criação de matrizes: m <- 1:20 # Vetor m dim(m) # Função que descreve n. de dimensões dim(m) <- c(5, 4) # Alterando n. de dimensões m dim(m) <- c(10, 2) # Alterando n. de dimensões m t(m) # Invertendo (transpondo) a matriz m # Note que as mudanças não são perenes... m <- t(m) # ...A não ser que sejam salvas m # Seleção de elementos: m[1, ] # 1ª linha m[ ,5] # 5ª coluna m[2,3] # Elemento da 2ª linha e 3ª coluna m ``` - **Data Frames**: Tabelas contendo vetores ou fatores de mesmo tamanho. **Pode possuir tipos diferentes.** Linhas/Rows também podem ser chamadas de *Casos/Cases* e Colunas/Columns de *Váriaveis/Variable*. ```r= # Data Frames # Criação de DFs df1 <- data.frame( ID = 1:5, Nome = c("Kuririn", "Goku", "Cell", "Piccolo", "Bulma"), Sexo = as.factor(c("M", "M", "M", "M", "F")), Idade = c(42, 46, 6, 26, 50), Especie = as.factor(c("Humano", "Sayajin", "Android", "Namekusei", "Humano")) ) df1 # Seleção de elementos: df1[1, ] # 1ª linha, todas as colunas df1[ ,2] # 2ª coluna, todas as linhas df1$Nome # Coluna "Nome" df1["Nome"] # Coluna "Nome" df1[c(1,3), ] # Linhas 1 e 3, todas as colunas df1[1:2, 2:5] # Linhas 1 e 2, colunas de 2 a 5 df1[df1$Idade > 30, c("Nome", "Especie")] # Das linhas cuja idades seja maior que 30, mostrar colunas "Nome" e "Especie" # Adicionando colunas df1$Poder <- c(150, 9000, 5500, 300, 10) df1 ``` ### Controle de fluxo Processos iterativos (em loop) que "quebram" o fluxo do código, realizando tarefas até que uma determinada condição seja satisfeita. - **for** Para *cada* elemento, faça algo. ```r= # for: # Para cada elemento de 1 a 10 for (i in 1:10) { # Exiba o resultado do elemento * 2 print(i * 2) } ``` - **if/else** Se uma condição for *verdadeira*, faça algo; Se não, faça outra coisa. ```r= # if/else: x <- 4 # Se módulo de x/2 for igual a 0 if (x %% 2 == 0) { # Exiba "par" print("par") # Se não } else { # Exiba "ímpar" print("ímpar") } ``` - **while** *Enquanto* uma condição se manter verdadeira, faça algo. ```r= # while: x <- 1 # Enquanto 'x' for menor que 10, faça: while (x <= 10) { # Exiba: print(paste("'x' agora é", x)) # Some 1 ao atual valor de 'x' x <- x + 1 } ``` ### Funções Aplicações para realizar ações específicas. Quase tudo é uma função. Das mais simples às mais complexas. Algumas funções já utilizadas: ***c(), length(), rep(), seq(), t(), data.frame()...*** Funções são pertencentes a pacotes nativos (built-in), carregados (instalados e convocados) ou criadas. Funções podem receber **argumentos** limitados, ilimitados, ou nem serem necessários. Alguns são opcionais, alguns são obrigatórios. Argumentos pode ou não ser nomeados. Se não forem, devem respeitar a ordem estabelecida pela função. Para checar os requisitos, usabilidade e exemplos do uso de uma função, utilize um `?` antes de seu nome. (Ex. `?length`) - **Built-in** As funções mais básicas são nativas. Pertencem a pacotes iniciados em conjunto com o R. ```r= # Funções built-in: # Funções sem necessidade de argumentos: # ls(): Lista os objetos ls() # getwd(): Informa o local de trabalho getwd() # Argumentos nomeados vs. não nomeados: ?round() round(x = 1.7468357) round(x = 1.7468357, digits = 3) round(digits = 3 , x = 1.7468357) round(1.7468357, 3) round(3, 1.7468357) # Funções específicas para determinados tipos de valores: sum(23, 12, 34, 45, 12, 59) sum("a", "b", "a", "d", "f") # erro ``` - **Funções criadas** É possivel criar uma função nova com a função: `function()`. ```r= # Funções criadas: critico <- function(titulo, nota){ if (nota <= 4 ){ paste("O filme", titulo, "é RUIM! Guarde seu dinheiro.") } else if (nota > 4 & nota < 8){ paste("O filme", titulo, "é MÉDIÃO! Só veja se não tiver algo melhor pra fazer.") } else { paste("O filme", titulo, "é ÓTIMO! Pode ver sem medo.") } } critico(titulo = "Morbius", nota = 3.5) critico("Avatar", 5.5) critico(nota = 9.5, titulo = "O Senhor dos Anéis") ``` - **Pacotes** Pacotes são conjuntos de funções que ampliam as capacidades do R. Esses pacotes devem ser instalados a parte e não são carregados automaticamente, requerendo uma convocação em seu primeiro uso. O R não possui a capacidade nativa de lidar com arquivos no formato `excel`. O pacote `xlsx` fornece funções para abrir e salvar arquivos nesse formato. ```r= # Funções de pacotes: # Instalação de pacotes - Execução única! install.packages("xlsx") # Convocação do pacote - Uma vez por sessão library("xlsx") # require("xlsx") também funciona # Funções de um pacote: # Digitar "pacote::" + tecla 'tab', ou: ls("package:xlsx") # Buscando ajuda: ?read.xlsx # Abrindo tabela do excel: pokedex <- read.xlsx(file = "/srv/cibioinfo/tutoriais/pokedex.xlsx", sheetIndex = 1) # Visualizando linhas iniciais, função : head(pokedex) # Visualizadno tabela inteira: View(pokedex) ``` ### Tidyverse: O melhores do R ![](https://i.imgur.com/uqq7psi.png) - Coleção de pacotes do R; - Compartilham estilo e síntaxe; Grande parte criado por Hadley Wickham; - Voltado à processos de *data wrangling*: - Obtenção, transformação, limpeza, agregação e visualização dos dados - Além de pacotes como `dplyr`, `tidyr` e `ggplot2`, o tidyverse adiciona o operador pipe (`%>%`), que permite o encadeamento de funções de forma mais intuitiva: ```r= # Instalação do 'tidyverse' já foi realizada préviamente (pesada!). # install.packages("tidyverse") # Convocação library("tidyverse") # Função única: sum(13, 18, 36, 16) sqrt(83) round(9.110434, digits = 2) # Ou a <- sum(13, 18, 36, 16) b <- sqrt(a) round(b, digits = 2) # Método de encadear funções no R Base (aninhamento): round(x = sqrt(sum(13, 18, 36, 16)), digits = 2) # Método com o pipe "%>%" sum(13, 18, 36, 16) %>% sqrt() %>% round(digits = 2) ``` ## 2. Básicos da exploração de dados em R ![](https://i.imgur.com/0HxNeUp.png =400x) ### Exploração - Estrutura dos dados ```r= # Recarregando a tabela: pokedex <- read.xlsx(file = "/srv/cibioinfo/tutoriais/pokedex.xlsx", sheetIndex = 1) # Visualização completa da tabela (aba): View(pokedex) # Visualização das primeiras linhas: head(pokedex) # Tamanho da tabela: ncol(pokedex) # N. de colunas nrow(pokedex) # N. de linhas # Resumo da tabela (tipos): str(pokedex) ``` - Variáveis, tipos e valores únicos ```r= # Checando os nomes: names(pokedex) # Tipo de variáveis: class(pokedex$Name) class(pokedex$Height_cm) # Valores únicos: unique(pokedex$Type1) ``` - Dados faltantes ```r= # Dados faltantes: # Ausência de dados pode ser um problema. No R, células vazias recebem 'NA' (not available). pokedex[ complete.cases(pokedex), ] pokedex[!complete.cases(pokedex), ] ``` ### Limpeza - Seleção de variáveis ```r= # Seleção de variáveis. Função 'select': names(pokedex) pokedex %>% select(1:2, 4) # por 'posição' pokedex %>% select(Number:Type2, Attack) # por 'nomes' pokedex %>% select(-Types, -Type2) # seleção negativa pokedex %>% select(Name, starts_with("Type")) # por padrão pokedex2 <- pokedex %>% select(Number:Weight_lb, HP:Speed) %>% select(-Types, -Type2) pokedex2 ``` - Mudando ordem de variáveis ```r= # Mudando ordem de variáveis. Função 'select': pokedex2 %>% select(Name, everything()) ``` - Mudando nomes de variáveis ```r= # Mudando nome de variáveis. Função 'rename': pokedex2 <- pokedex2 %>% # Sintaxe: rename(nome_novo = nome_velho) rename(Type = Type1) ``` - Mudando o tipo de variáveis ```r= # Mudando o tipo de variáveis: class(pokedex2$Type) pokedex2$Type <- as.factor(pokedex2$Type) class(pokedex2$Type) levels(pokedex2$Type) ``` - Filtrando linhas ```r= # Filtrando linhas: pokedex2 %>% select(Name, Type, Attack) %>% # Filtando por uma condição filter(Type == "fire") pokedex2 %>% select(Name, Type, Attack) %>% # Filtando se uma condição OU outra for verdadeira filter(Type == "fire" | Type == "water") pokedex2 %>% select(Name, Type, Attack) %>% # Filtando se uma condição E outra forem verdadeiras filter(Type == "fire" & Attack >= 100) pokedex2 %>% select(Name, Type, Attack) %>% # Soma dos filtros anteriores filter((Type == "fire" | Type == "water") & Attack >= 100) ``` - Lidando com dados perdidos ("NAs") ```r= # Lidando com "NAs" mean(pokedex2$Attack) # Erro mean(pokedex2$Attack, na.rm = TRUE) pokedex2 <- pokedex2 %>% drop_na() mean(pokedex2$Attack) ``` ### Manipulação - Criando ou alterando variável ```r= # Criando ou alterando variáveis. Função 'mutate': pokedex2 <- pokedex2 %>% mutate(Height_m = Height_cm / 100) %>% mutate(Weight_kg = Weight_lb / 2.205) %>% select(-Height_cm, -Weight_lb) View(pokedex2) ``` - Mudança condicional ```r= # Mudança condicional. Funtção 'mutate' + 'if_else': pokedex2 <- pokedex2 %>% mutate(Power = if_else(Attack >= 120 | Special >= 120, "High", "Low")) View(pokedex2) ``` ### Descrição - Amplitude e Dispersão ```r= # Amplitude: Mínimas e máximas: min(pokedex2$Height_m) max(pokedex2$Height_m) range(pokedex2$Height_m) # Dispersão IQR(pokedex2$Height_m) boxplot(pokedex2$Height_m, horizontal = T) ``` - Centralidade ```r= # Centalidade mean(pokedex2$Attack) median(pokedex2$Attack) ``` - Variância e Desvio-Padrão ```r= # Variância e Desvio-Padrão var(pokedex2$Attack) var(pokedex2$Height_m) sd(pokedex2$Attack) sd(pokedex2$Height_m) par(mfrow=c(1,2)) boxplot(pokedex2$Attack, horizontal = T) boxplot(pokedex2$Height_m, horizontal = T) par(mfrow=c(1,1)) ``` - Resumo dos dados ```r= # Resumos summary(pokedex2$Attack) summary(pokedex2$Height_m) pokedex2 %>% select(Attack, Defense, Height_m, Weight_kg) %>% summary() ``` - Criação de tabelas de resumos ```r= # Criação de tabelas de resumos table(pokedex2$Type) tipo_freq <- pokedex2 %>% select(Type) %>% table() View(tipo_freq) tipo_atk <- pokedex2 %>% # Remove colunas não-agrupaveis e não-numéricas select(-Number, -Name) %>% # Agrupa pelo fator em comum group_by(Type) %>% # Cria as medidas as quais se deseja avaliar summarise(Min = min(Attack), Max = max(Attack), Mean = mean(Attack), SD = sd(Attack)) %>% # Ordena de forma decrescente ('-') arrange(-Mean) tipo_sp <- pokedex2 %>% select(-Number, -Name) %>% group_by(Type) %>% summarise(Min = min(Special), Max = max(Special), Mean = mean(Special), SD = sd(Special)) %>% arrange(-Mean) View(tipo_atk) View(tipo_sp) ``` ### Visualização ![](https://i.imgur.com/n2m1Wal.png =100x) - **ggplot2** - Um dos melhores pacotes do R para visualização de dados; - Permite a construção modular de gráficos; - Possui uma "gramática" própria (*"A Gramática dos Gráficos"*). Básicamente, necessita de três informações: `data`, `mapping` e `geometry` - Inicialmente parece complexo, mas é compensado por sua versatilidade; - Cheat Sheet: [Link](https://github.com/rstudio/cheatsheets/blob/main/data-visualization-2.1.pdf) - Gráficos de barra ```r= # Gráfico de barras ggplot(data = pokedex2, mapping = aes(x = Type)) + geom_bar() ggplot(data = pokedex2, mapping = aes(x = Type, fill = Type)) + geom_bar() cores <- c("#a8b821", "#6e39fd", "#f7d432", "#c03121", "#f07f2f", "#6f5997", "#78c750", "#e0c167", "#98d8d8", "#a9a878", "#9f3fa0", "#fc5686", "#b89f38", "#6294e9") ggplot(data = pokedex2, mapping = aes(x = Type, fill = Type)) + geom_bar() + scale_fill_manual(values=cores) ``` - Histogramas ```r= # Histogramas ggplot(data = pokedex2, mapping = aes(x = Height_m)) + geom_histogram() ggplot(data = pokedex2, mapping = aes(x = Height_m)) + geom_histogram(colour = "black", fill = "white", bins = 100) ggplot(data = pokedex2, mapping = aes(x = Height_m)) + geom_histogram(colour = "black", fill = "white", bins = 20) ``` - Diagrama de caixa (Boxplot) ```r= # Diagrama de caixa (Boxplot) ggplot(data = pokedex2, mapping = aes(y = Defense)) + geom_boxplot() ggplot(data = pokedex2, mapping = aes(y = Attack, x = Type)) + geom_boxplot() ggplot(data = pokedex2, mapping = aes(y = Special, x = Type, fill = Type)) + geom_boxplot() + scale_fill_manual(values=cores) + theme_bw() ``` - Gráfico de densidade ```r= # Gráfico de densidade pokedex2 %>% filter(Type %in% c("psychic", "fighting")) %>% ggplot(aes(x = Attack, color = Type, fill = Type)) + geom_density(alpha = 0.8) + theme_bw() + scale_fill_manual(values=c("#c03121", "#fc5686")) + scale_color_manual(values=c("#c03121", "#fc5686")) pokedex2 %>% filter(Type %in% c("psychic", "fighting")) %>% ggplot(aes(x = Special, color = Type, fill = Type)) + geom_density(alpha = 0.8) + theme_bw() + scale_fill_manual(values=c("#c03121", "#fc5686")) + scale_color_manual(values=c("#c03121", "#fc5686")) ``` - Gráfico de dispersão ```r= # Gráfico de dispersão pokedex2 %>% ggplot(aes(Speed, HP)) + geom_point(size = 3, alpha = 0.8) + theme_bw() + labs(title = "Velocidade vs. HP") pokedex2 %>% ggplot(aes(Attack, Defense)) + geom_point(size = 3, alpha = 0.8) + theme_bw() + labs(title = "Defesa vs. Ataque") pokedex2 %>% ggplot(aes(Attack, Defense, color = Type)) + geom_point(size = 3, alpha = 0.8) + theme_bw() + scale_color_manual(values=cores) + labs(title = "Defesa vs. Ataque") ``` - Gráfico de tendência ```r= # Gráfico de tendência pokedex2 %>% ggplot(aes(Attack, Defense)) + geom_point(size = 3, alpha = 0.8) + geom_smooth() + theme_bw() + labs(title = "Defesa vs. Ataque") pokedex2 %>% ggplot(aes(Attack, Defense)) + geom_point(size = 3, alpha = 0.8) + geom_smooth(method = "lm") + theme_bw() + labs(title = "Defesa vs. Ataque") ```