R: Data frames e fatores no R

Última atualização: 2026-08-26

Nas últimas 9 aulas, aprendemos sobre vetores, matrizes e listas — cada um deles com suas limitações. Data frames (data.frame) resolvem todos esses problemas: são tão fáceis de ler quanto uma planilha do Excel e tão eficientes quanto uma matriz. Nesta aula, vamos aprender sobre a verdadeira “estrela” do R — o data frame.

Os data frames e o tidyverse estão no cerne da ciência de dados no R. A partir desta aula, vamos mergulhar oficialmente no mundo da “análise de dados com o R”.

1. O que você vai aprender



2. Uma história sobre como converter arquivos do Excel para o R

(1) Problema: o Excel não consegue lidar com isso

A planilha de pesquisa de mercado de Chen tem 10.000 linhas × 8 colunas:

TEXT 📖 Somente leitura
EmployeesID  Name  Department    Salary   Years Performance Gender Start Date
2024001 Alice  Data Department  15000  3    A   M  2021-03-15
2024002 Bob  Engineering Department  18000  5    A+  M  2019-08-20
...

Calcular os salários médios por “departamento”, classificar por “desempenho” e identificar os funcionários com salários mais altos... Isso leva 30 minutos no Excel, com fórmulas aninhadas a ponto de travar o programa.

(2) Solução usando R

R
library(dplyr)

# 5 Code execution complete 5 An Analysis
df |>
  group_by(Department) |>
  summarise(Average Wage = mean(Salary), Number of people = n()) |>
  arrange(desc(Average Wage)) |>
  filter(Average Wage > 15000)

5 linhas de código em vez de 30 minutos no Excel. Esse é o poder do DataFrame + dplyr.



3. data.frame: o “personagem principal” do R

(1) O que é um data frame?

100%
graph TB
    A["Data Frame data.frame"] --> B["Each column = 1 equal-length vectors"]
    A --> C["Each line = 1 records"]
    A --> D["Mixed Types(Each column is independent)"]
    A --> E["The bottom layer is'A list of vectors of equal length'"]
    
    style A fill:#fff3cd
    style B fill:#cce5ff
    style C fill:#d4edda
    style D fill:#f8d7da
    style E fill:#e1d4ff

Um data frame é uma "lista de vetores de comprimento igual":

(2) Criar um data frame

R
# Methods 1:data.frame()(Basics R)
df <- data.frame(
  name = c("Alice", "Bob", "Charlie"),
  age = c(25, 30, 35),
  score = c(95, 88, 92),
  passed = c(TRUE, TRUE, TRUE)
)
print(df)
#       name age score passed
# 1    Alice  25    95   TRUE
# 2      Bob  30    88   TRUE
# 3 Charlie  35    92   TRUE

# Methods 2:tibble(tidyverse Version,Recommendations)
# install.packages("tibble")
library(tibble)
df2 <- tibble(
  name = c("Alice", "Bob", "Charlie"),
  age = c(25, 30, 35),
  score = c(95, 88, 92)
)
print(df2)

(3) data.frame x tibble

Função data.frame tibble
Imprimir Imprimir todas as linhas por padrão (pode fazer com que o sistema trave ao lidar com conjuntos de dados grandes) Imprimir as primeiras 10 linhas + tipos de colunas por padrão
Nome da coluna Aceita caracteres especiais Verificar validade
Subconjunto de um subconjunto df[, "col"] Retorna um vetor Sempre retorna um tibble
Desempenho Mais lento Mais rápido
String Converter em fator por padrão Manter como string
R
# View Structure
str(df)
# 'data.frame':	3 obs. of  4 variables:
#  $ name  : chr  "Alice" "Bob" "Charlie"
#  $ age   : num  25 30 35
#  $ score : num  95 88 92
#  $ passed: logi  TRUE TRUE TRUE

# Summary Statistics
summary(df)
#      name                age        score          passed
#  Length:3           Min.   :25   Min.   :88   Mode :logical
#  Class :character   1st Qu.:27   Median :92   TRUE:3
#  Mode  :character   Mean   :30   Mean   :91   NA's :0
#                     3rd Qu.:32   3rd Qu.:93
#                     Max.   :35   Max.   :95


4. Acesso a DataFrames

(1) 4 maneiras de acessar

Método Sintaxe Retorno Finalidade
df[i, j] Linha i, coluna j Escalar/Vetor/DataFrame Combinação de linha e coluna
df[i, ] Linha i DataFrame Obter linha
df[, j] Coluna j Vetor (R básico) / Quadro de dados Extrair coluna
df$name Por nome da coluna Vetor Obter coluna
df[["name"]] Por nome da coluna Vetor Obter coluna
R
df <- data.frame(
  name = c("Alice", "Bob", "Charlie"),
  age = c(25, 30, 35),
  score = c(95, 88, 92)
)

# Retrieve a single element
df[2, 3]              # [1] 88
df[2, "score"]        # [1] 88

# Select the entire row
df[1, ]               # Entire row (Data Frame)
#     name age score
# 1 Alice  25    95

# Round an entire column
df[, "age"]           # Digital Vectors [1] 25 30 35
df$age                # Ibid.
df[["age"]]           # Ibid.

(2) Índice lógico (filtro)

R
# Find the Fraction > 90 line
df[df$score > 90, ]
#       name age score
# 1    Alice  25    95
# 3 Charlie  35    92

# Multiple conditions
df[df$age > 25 & df$score > 85, ]

(3) ⚠️ Importante: Como recuperar colunas no R básico em comparação com o tibble

R
# base R:Retrieve the column return vector
df[, "age"]           # [1] 25 30 35  ← Digital Vectors

# tibble:Retrieve and return the column tibble
library(tibble)
tb <- as_tibble(df)
tb[, "age"]           # ← tibble(1 row 1 col)

# Want to extract a vector from tibble: Use [[ ]] or $
tb[["age"]]           # [1] 25 30 35  ← Digital Vectors
⚠️ Observação: o [, "col"] do tibble não é convertido automaticamente em um vetor. Trata-se de um recurso de “segurança” do design — ele impede que o sistema interprete erroneamente grandes data frames como vetores, o que poderia causar o congelamento de toda a saída de dados.



5. Modificação da estrutura de dados

(1) Adicionar uma coluna

R
# Use $ to add
df$city <- c("Beijing", "Shanghai", "Guangzhou")

# Use transform()
df <- transform(df, bonus = score * 100)

# Use within() to reference column names
df <- within(df, level <- ifelse(score >= 90, "A", "B"))

print(df)
#       name age score   city bonus level
# 1    Alice  25    95   Beijing  9500     A
# 2      Bob  30    88   Shanghai  8800     B
# 3 Charlie  35    92   Guangzhou  9200     A

(2) Modificar colunas

R
# Array Assignment
df$age <- df$age + 1

# Condition Modification
df$score[df$name == "Bob"] <- 90

(3) Excluir uma coluna

R
# Assign NULL
df$bonus <- NULL
df$level <- NULL

(4) Adicionar/Excluir linhas

R
# Add a row: Use rbind
new_row <- data.frame(name = "Diana", age = 28, score = 85, city = "Shenzhen")
df <- rbind(df, new_row)

# Delete Row:Using Negative Indexes
df <- df[-1, ]  # Delete 1st row


6. Fator: variável categórica

(1) Por que os fatores são necessários?

No R, usar fatores para representar variáveis categóricas (como “baixo/médio/alto”) é mais eficaz do que usar vetores de caracteres:

R
# Character vector(Disorder)
gender_char <- c("M", "F", "M", "F", "M")

# factor(Orderly + Finite values)
gender_factor <- factor(gender_char, levels = c("M", "F"))
gender_factor
# [1] M F M F M
# Levels: M F

(2) As vantagens dos fatores

100%
graph TB
    A["Character vector 'Low' 'Mid' 'High'"] --> B["factor factor<br/>+ levels Order<br/>+ Finite values<br/>+ Save memory"]
    A --> C["Disadvantages: Cannot sort and compare"]
    B --> D["Advantages: Can be compared for size<br/>Can be grouped in order<br/>Statistics/Knowing the Number of Categories in Modeling"]
    
    style A fill:#f8d7da
    style B fill:#d4edda
    style D fill:#cce5ff
R
# Compare Sizes(Characters cannot,Factors can)
sizes <- factor(c("S", "L", "Mid", "L", "S"),
                levels = c("S", "Mid", "L"),
                ordered = TRUE)

sizes[1] < sizes[2]   # TRUE  <- Characters can't do that!

(3) Operações comuns com fatores

R
# View levels
levels(sizes)
# [1] "S" "Mid" "L"

# Frequency Count
table(sizes)
# sizes
# S Mid L
#  2  1  2

# Reorder
sizes <- factor(sizes, levels = c("L", "Mid", "S"))  # Reverse the order
levels(sizes)
# [1] "L" "Mid" "S"
⚠️ Observação: Na era do tidyverse, recomenda-se usar o pacote forcats (abordado na Lição 11) para lidar com fatores, pois ele é mais elegante do que o R básico.

(4) Fatores na estrutura de dados

R
# data.frame() Convert character strings to factors by default (This is a trap!)
df <- data.frame(
  name = c("Alice", "Bob"),  # Character vector
  stringsAsFactors = FALSE   # Disable Auto-Conversion(Recommendations)
)
str(df)
# $ name: chr "Alice" "Bob"  ← Preserve characters
💡 Dica: A nova versão do R (4.x) usa stringsAsFactors = FALSE por padrão, mas códigos mais antigos podem usar um valor diferente. Recomenda-se escrever explicitamente stringsAsFactors = FALSE.



7. Introdução ao dplyr: os cinco fundamentos do processamento de dados

dplyr está no cerne do tidyverse; cinco funções abrangem 80% dos cenários de processamento de dados:

(1) Instalação e carregamento

R
install.packages("dplyr")
library(dplyr)

(2) Função de cinco partes

Função Finalidade Equivalente em SQL
filter() Filtrar linhas WHERE
select() Selecionar coluna SELECT
mutate() Adicionar/Modificar coluna
arrange() Ordenar ORDER BY
summarise() Estatísticas agregadas GROUP BY

(3) O operador encadeado |>

R
# |> is R 4.1+'s "pipe symbol", Pass the result from the previous step to the next step
df |> filter(age > 25) |> select(name, age)

(4) Prática: Processamento de dados de funcionários

R
# Prepare the data
employees <- tibble(
  id = 2024001:2024010,
  name = c("Alice", "Bob", "Charlie", "Diana", "Eve",
           "Frank", "Grace", "Henry", "Ivy", "Jack"),
  department = c("Data Department", "Engineering Department", "Data Department", "Product Department", "Engineering Department",
                "Data Department", "Engineering Department", "Product Department", "Data Department", "Engineering Department"),
  salary = c(15000, 18000, 16000, 20000, 17000,
            15500, 19000, 21000, 16500, 17500),
  years = c(3, 5, 4, 7, 4, 2, 6, 8, 3, 5),
  performance = factor(
    c("A", "A+", "B", "A+", "A", "B", "A", "A+", "B", "A"),
    levels = c("B", "A", "A+"),
    ordered = TRUE
  )
)

# 1. filter:Screening Data Department Employees
data_dept <- employees |> filter(department == "Data Department")

# 2. select:Select a subset of columns
basic_info <- employees |> select(name, department, salary)

# 3. mutate:Add an "Annual Salary" column
employees <- employees |> mutate(annual_salary = salary * 12)

# 4. arrange:Sort by salary in descending order
ranked <- employees |> arrange(desc(salary))

# 5. summarise:By Department
dept_stats <- employees |>
  group_by(department) |>
  summarise(
    Number of people = n(),
    Average Wage = mean(salary),
    Highest Salary = max(salary),
    Total Annual Salary = sum(annual_salary)
  ) |>
  arrange(desc(Average Wage))

print(dept_stats)
# # A tibble: 3 × 5
#   department Number of people Average Wage Highest Salary Total Annual Salary
#   <chr>    <int>    <dbl>    <dbl>  <dbl>
# 1 Product Department       2   20500    21000 492000
# 2 Engineering Department       4   17875    19000 858000
# 3 Data Department       4   15750    16500 756000

(5) Exemplo de uma combinação de 5 etapas

R
# Comprehensive Example:Identify High-Performing, High-Earning Employees
top_talent <- employees |>
  filter(performance %in% c("A+", "A")) |>     # Performance Screening A+ or A
  filter(salary > 16000) |>                     # ② Filter by High Salary
  mutate(salary_level = ifelse(salary > 18000, "High", "Upper-middle")) |>  # ③ Add Category
  arrange(desc(salary)) |>                      # ④ Sort
  select(name, department, salary, performance, salary_level)  # ⑤ Select Column

print(top_talent)
# # A tibble: 3 × 5
#   name   department salary performance salary_level
#   <chr>  <chr>       <dbl> <ord>       <chr>       
# 1 Henry  Product Department      21000 A+          High          
# 2 Diana  Product Department      20000 A+          High          
# 3 Bob    Engineering Department      18000 A+          Upper-middle
▶ Experimente

8. Exemplo completo: Análise abrangente dos dados dos funcionários

A seguir, apresentamos um exemplo de um fluxo de trabalho completo que reúne todos os conceitos abordados nesta aula.

▶ Exemplo: Análise abrangente dos dados dos funcionários da empresa

R 📖 Somente leitura
# ============================================
# Comprehensive Analysis of Company Employee Data
# Features:Using a DataFrame + dplyr Comprehensive Analysis 10 employees
# ============================================

library(dplyr)

# 1. Prepare data
employees <- tibble(
  id = 2024001:2024010,
  name = c("Alice", "Bob", "Charlie", "Diana", "Eve",
           "Frank", "Grace", "Henry", "Ivy", "Jack"),
  department = c("Data Department", "Engineering Department", "Data Department", "Product Department", "Engineering Department",
                "Data Department", "Engineering Department", "Product Department", "Data Department", "Engineering Department"),
  salary = c(15000, 18000, 16000, 20000, 17000,
            15500, 19000, 21000, 16500, 17500),
  years = c(3, 5, 4, 7, 4, 2, 6, 8, 3, 5),
  performance = factor(
    c("A", "A+", "B", "A+", "A", "B", "A", "A+", "B", "A"),
    levels = c("B", "A", "A+"),
    ordered = TRUE
  )
)

cat("=== Raw Data ===\n")
print(employees)

# 2. View Structure
cat("\n=== Data Structures ===\n")
str(employees)

# 3. Summary Statistics
cat("\n=== Abstract ===\n")
summary(employees)

# 4. By Department
cat("\n=== By Department ===\n")
dept_summary <- employees |>
  group_by(department) |>
  summarise(
    Number of people = n(),
    Average Wage = mean(salary),
    Median Wage = median(salary),
    Highest Salary = max(salary),
    Minimum Wage = min(salary),
    Average Length of Service = round(mean(years), 1)
  ) |>
  arrange(desc(Average Wage))
print(dept_summary)

# 5. Identify High-Performing Employees (A+ or A)
cat("\n=== Employees with Outstanding Performance ===\n")
top_perf <- employees |>
  filter(performance %in% c("A+", "A")) |>
  arrange(desc(salary)) |>
  select(name, department, salary, performance, years)
print(top_perf)

# 6. Add"Pay Grade"col
cat("\n=== Salary Grade Classification ===\n")
employees <- employees |>
  mutate(
    salary_level = factor(
      ifelse(salary >= 18000, "High",
      ifelse(salary >= 16000, "Mid", "Low")),
      levels = c("Low", "Mid", "High"),
      ordered = TRUE
    ),
    annual_salary = salary * 12
  )

# By Pay Grade
level_summary <- employees |>
  group_by(salary_level) |>
  summarise(Number of people = n(), Average Wage = mean(salary))
print(level_summary)

# 7. Identify the Best Employees (High Salary + High Performance + Senior)
cat("\n=== Top Employee (High Salary + Outstanding Performance + Senior) ===\n")
top_talent <- employees |>
  filter(salary >= 17000, performance == "A+", years >= 5) |>
  select(name, department, salary, years, performance, annual_salary)
print(top_talent)
61 linhas de lógica (limite de 40, somente leitura)

Resultado esperado (trecho):

TEXT 📖 Somente leitura
=== By Department ===
# A tibble: 3 × 7
  department  Number of people Average Wage Median Wage Highest Salary Minimum Wage Average Length of Service
  <chr>     <int>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
1 Product Department        2   20500    20500    21000    20000      7.5
2 Engineering Department        4   17875    17750    19000    17000      4.5
3 Data Department        4   15750    15750    16500    15000      3  

=== Employees with Outstanding Performance ===
# A tibble: 6 × 5
  name   department salary performance years
  <chr>  <chr>       <dbl> <ord>       <dbl>
1 Henry  Product Department      21000 A+              8
2 Diana  Product Department      20000 A+              7
3 Bob    Engineering Department      18000 A+              5
4 Grace  Engineering Department      19000 A                6
5 Eve    Engineering Department      17000 A                4
6 Jack   Engineering Department      17500 A                5

❓ Perguntas Frequentes

P: Como faço para escolher entre data.frame e tibble? R: Use tibble para novos projetos — ele é mais adequado para impressão, tem melhor desempenho e possui tipos de dados mais restritos. Enquanto estiver aprendendo, comece com data.frame (não é preciso carregar nenhum pacote) e mude para tibble assim que estiver familiarizado com ele.

P: Quais são as vantagens dos fatores? R: Três vantagens principais: ① Podem ser comparados quanto à magnitude (ordered = TRUE) ② Economizam memória (armazenam apenas codificações inteiras) ③ Permitem a análise estatística e a modelagem quando o número de categorias é conhecido (evitando o problema do “valor desconhecido”). O tidyverse recomenda o uso do pacote forcats para lidar com fatores.

P: Qual é a relação entre o dplyr e o R básico? R: O dplyr é uma camada de abstração moderna para o R básico. filter(df, ...) substitui df[...], e select(df, ...) substitui df[, ...]. O dplyr é mais legível e consistente, além de seguir o padrão tidyverse para ciência de dados.

P: Qual é a diferença entre |> e %>%? R: |> é o símbolo de pipe nativo do R 4.1+ (não é necessário carregar nenhum pacote), enquanto %>% é o símbolo de pipe do pacote magrittr (o antigo tidyverse). O código mais recente usa |>, mas %>% ainda é comum em códigos e tutoriais mais antigos.

P: Qual é a diferença entre mutate e transform? R: mutate() pode fazer referência a uma coluna que acabou de ser criada (mutate(df, y = x * 2, z = y + 1)), enquanto transform() não pode. É por isso que mutate é mais popular no tidyverse.


📖 Resumo


📝 Exercícios

  1. Exercício básico: Use data.frame() para criar um dataframe students (6 alunos × 4 colunas: nome/idade/nota/aprovado). Imprima os dataframes str() e summary() e acesse todas as colunas da terceira linha.

  2. Problema básico: Converta a coluna name do problema anterior para factor (3 níveis) e compare as diferenças entre as.character() e as.numeric(). Verifique se o fator permite a comparação de magnitudes (>).

  3. Problema básico: Instale e carregue dplyr; em seguida, use filter() para filtrar os alunos de score > 85 com base no students do problema anterior e classifique-os em ordem decrescente por pontuação usando arrange().

  4. Exercício avançado: Use tibble para criar um data frame sales (10 linhas × 4 colunas: produto/região/valor/data). ① Use mutate() para somar discount = amount * 0.1; ② Use group_by(region) + summarise() para calcular o total de vendas de cada região; ③ Use arrange(desc()) para classificar as regiões.

  5. Desafio: Utilizando dados simulados de funcionários (10 funcionários, 3 departamentos, salário/anos de serviço/desempenho), conclua a análise em 7 etapas: ① Carregue o dplyr ② Calcule o número de funcionários e o salário médio por departamento ③ Identifique os funcionários com salários altos e ≥ 5 anos de serviço ④ Use mutate para adicionar uma coluna de salário anual ⑤ Use case_when (ou ifelse) para categorizar por faixas salariais ⑥ Classifique por desempenho ⑦ Grave em um novo data frame top_employees e salve como um arquivo CSV (write.csv()).

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%