R: Listas do R: O “Container Universal” do R

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

Nas três aulas anteriores, aprendemos sobre vetores e matrizes — ambos exigem que todos os elementos sejam do mesmo tipo. No entanto, na realidade, os dados costumam ser heterogêneos: as informações dos alunos incluem o número de identificação (números), o nome (caracteres) e as notas (vetores). O R usa listas para resolver o problema do armazenamento de dados heterogêneos.

As listas são o verdadeiro “canivete suíço” do R — elas podem conter qualquer tipo (vetores, matrizes, data frames, funções ou até mesmo outras listas). Os data frames data.frame são, em essência, “listas de vetores de comprimento igual”. Esta lição é fundamental para a Fase 1.

1. O que você vai aprender



2. Uma história sobre a gestão de informações dos alunos

(1) Desafio: Armazenamento heterogêneo de dados

Ivan trabalha no RH e precisa armazenar todas as informações de um funcionário:

TEXT 📖 Somente leitura
Employee ID:2024001(Numbers)
Name:Alice(Character)
Department:Data Analysis Department(Character)
Salary:15000(Numbers)
Skills:c("R", "Python", "SQL")(Character vector)

Se você usar um vetor, todos os elementos devem ser do mesmo tipo — isso não vai funcionar. Se você usar um data frame, cada coluna deve ter o mesmo número de colunas — isso também não vai funcionar.

(2) Solução utilizando listas

R
# One list Fits all types
employee <- list(
  id = 2024001,
  name = "Alice",
  department = "Data Analysis Department",
  salary = 15000,
  skills = c("R", "Python", "SQL"),
  is_active = TRUE
)

# Access any field
employee$name           # [1] "Alice"
employee$skills[1]      # [1] "R"
employee$salary * 12    # [1] 180000  (Annual Salary)

Uma única lista contendo 6 campos de tipos diferentes. Esse é o poder das listas do R.



3. list(): Criar uma lista

(1) Sintaxe básica

R
list(key1 = value1, key2 = value2, ...)

(2) 5 maneiras de criar

R
# 1. List of Names(Most Commonly Used)
person <- list(name = "Alice", age = 25, scores = c(85, 90, 92))
person
# $name
# [1] "Alice"
# 
# $age
# [1] 25
# 
# $scores
# [1] 85 90 92

# 2. Anonymous List(Browse by Location)
unnamed <- list("a", 1, TRUE)
# [[1]] "a"
# [[2]] 1
# [[3]] TRUE

# 3. Nested Lists
company <- list(
  hr = list(name = "HR", count = 5),
  it = list(name = "IT", count = 20)
)

# 4. Empty list
empty <- list()
length(empty)  # [1] 0

# 5. Use list() to convert vector (Maintain Heterogeneity)
as.list(c(1, 2, 3))
# [[1]] 1
# [[2]] 2
# [[3]] 3

(3) Comparação entre listas e vetores

100%
graph TB
    A[R Data Structures] --> B[Vector<br/>Homogeneous<br/>One-dimensional]
    A --> C[Matrix<br/>Homogeneous<br/>Two-dimensional]
    A --> D[List<br/>Heterogeneous<br/>Any type]
    A --> E[Data Frame<br/>List of vectors of equal length<br/>Two-dimensional]
    
    style A fill:#fff3cd
    style B fill:#cce5ff
    style C fill:#d4edda
    style D fill:#f8d7da
    style E fill:#e1d4ff
Imóvel Vector c(1, 2, 3) Lista list(1, "a", TRUE)
Tipo de elemento Deve ser o mesmo Pode ser diferente
Tipo de elemento 6 tipos básicos Qualquer objeto R (incluindo funções e data frames)
Visita v[1] l[[1]]
Comprimento variável ✅ (Pode ser acrescentado ou removido conforme desejado)
Semelhante ao Python tuple dict / list


4. 4 Métodos de acesso (Pontos-chave)

(1) 4 tipos de tabelas de consulta

Método Sintaxe Retorno Finalidade
[[i]] O i-ésimo elemento O próprio elemento Recuperar um único elemento
[i] O i-ésimo elemento Sublista Selecionar um subconjunto
$name Por nome O próprio elemento Obter o elemento nomeado
[["name"]] Por nome O próprio elemento Equivalente $name

(2) [[ ]] x [ ]: Principais diferenças

R
person <- list(name = "Alice", age = 25, scores = c(85, 90, 92))

# [[ ]] Return the element itself
person[[1]]
# [1] "Alice"  ← Character

# [ ] Return to Sublist
person[1]
# $name
# [1] "Alice"  ← Or a list

# Key Differences: Using [ ] after extraction, attempting to access sub-elements may cause an error
person[1]$name  # ✅ $name Still accessible(Syntax sugar)
person[1][1]    # ❌ This is the 1 element,But there is only one child list $name

# Practical Application:Calculate the average score
mean(person[[3]])      # [1] 89  ← [[3]] Extract the vector
mean(person$scores)    # [1] 89  ← $scores Extract the vector
mean(person[3])        # Error: need numeric data
⚠️ Observação: Use [[ ]] ou $ para acessar elementos e [ ] para acessar subconjuntos. Esse é o aspecto mais confuso do acesso a listas no R.

(3) $ vs [["name"]]

R
# $ is syntactic sugar for [[ "name" ]]
person$name           # Equivalent person[["name"]]
person[["name"]]      # Equivalent person$name

# $ Supports partial matches(Not recommended)
person$na             # Automatically matched to "name"
# [1] "Alice"

# [[ ]] Partial matches are not supported(Safer)
person[["na"]]        # Error
💡 Dica: Use [[ "name" ]] para o código de produção — é claro e inequívoco, e não depende de correspondências parciais.

(4) Acesso a listas aninhadas

R
company <- list(
  hr = list(name = "HR", count = 5, head = "Alice"),
  it = list(name = "IT", count = 20, head = "Bob")
)

# Accessing Nested Elements
company$hr$head                  # [1] "Alice"
company[["it"]][["head"]]        # [1] "Bob"
company$it$count                 # [1] 20


5. Modificar, adicionar e excluir itens de uma lista

(1) Modificar um elemento

R
person <- list(name = "Alice", age = 25)

# Edit ([[ ]] or $ both can be changed)
person$age <- 26
person[["age"]]
# [1] 26

# Batch Edit
person$age <- person$age + 1
person$age  # [1] 27

(2) Adicionar um elemento

R
# Methods 1: Use $ to add
person$email <- "alice@example.com"

# Methods 2: Use [[ ]] to add
person[["phone"]] <- "13800000000"

# Methods 3: Use c() to merge
person <- c(person, address = "Haidian District, Beijing")

(3) Exclusão de elementos

R
# Assign NULL to delete
person$phone <- NULL

# Or
person[["address"]] <- NULL

(4) Visualizar a estrutura da lista

R
# View Structure(Important Debugging Functions)
str(person)
# List of 4
#  $ name    : chr "Alice"
#  $ age     : num 27
#  $ email   : chr "alice@example.com"
#  $ address : chr "Haidian District, Beijing"

# View All Names
names(person)
# [1] "name" "age" "email" "address"


6. lapply(): Processamento em lote de listas

(1) Por que usar o lapply?

Os tipos de elementos em uma lista podem variar — não é possível simplesmente usar sum() mean(). A função lapply nos permite aplicar uma função a cada elemento:

R
mixed_list <- list(
  numbers = 1:5,
  chars = c("a", "b", "c"),
  logical = c(TRUE, FALSE, TRUE)
)

# Calculate the length of each element
lapply(mixed_list, length)
# $numbers
# [1] 5
# 
# $chars
# [1] 3
# 
# $logical
# [1] 3

(2) lapply + Função personalizada

R
# CalculateFor each element,"Abstract"
summary_list <- lapply(mixed_list, function(x) {
  if (is.numeric(x)) {
    return(list(mean = mean(x), sum = sum(x)))
  } else {
    return(list(length = length(x), class = class(x)))
  }
})

summary_list$numbers
# $mean
# [1] 3
# 
# $sum
# [1] 15

(3) Simplificando os resultados com sapply()

R
# lapply Back to List,sapply Simplify to a vector
sapply(mixed_list, length)
# numbers    chars  logical 
#       5        3        3


7. Unificação de listas: c() e unlist()

(1) c() Mesclar listas

R
# Merge Multiple Lists
list1 <- list(a = 1, b = 2)
list2 <- list(c = 3, d = 4)

merged <- c(list1, list2)
merged
# $a 1
# $b 2
# $c 3
# $d 4

(2) A função unlist() transforma o objeto em um vetor

R
# Flatten the list into a vector(Only for"Atom"Element Valid)
numbers_list <- list(a = 1, b = 2, c = 3)
unlist(numbers_list)
# a b c
# 1 2 3

# Note:The type will be coerced after flattening.
mixed <- list(1, "a", TRUE)
unlist(mixed)
# [1] "1"    "a"    "TRUE"  ← Convert All to Strings


8. list2env(): Converte uma lista em um ambiente

Transforme cada elemento da lista em uma variável global:

R
config <- list(
  host = "localhost",
  port = 3306,
  user = "root",
  password = "secret"
)

# Convert list elements to environment variables
list2env(config, envir = .GlobalEnv)

# You can use it right away
host    # [1] "localhost"
port    # [1] 3306
⚠️ Observação: list2env() pode contaminar o ambiente global; portanto, use com cautela. É mais comumente utilizado em cenários em que as configurações são carregadas a partir de YAML ou JSON.



9. Comparação de operações comuns

(1) c() x list() x unlist()

Função Finalidade Entrada → Saída
c() Combinação de elementos atômicos c(1, 2, 3) → Vetores
list() Criar um contêiner heterogêneo list(1, "a") → Lista
unlist() Transformar a lista em um vetor unlist(list(1,2,3)) → Vetor

(2) Conversão de uma lista em um DataFrame

R
# A list of vectors of equal length can be converted data.frame
df <- as.data.frame(list(
  name = c("A", "B", "C"),
  age = c(20, 25, 30),
  score = c(85, 90, 78)
))
print(df)
#   name age score
# 1    A  20    85
# 2    B  25    90
# 3    C  30    78
💡 Dica: Um data frame é, essencialmente, uma “lista de vetores de comprimento igual” — vamos explorar isso com mais profundidade na próxima aula.



10. Exemplo completo: Gerenciamento de registros de funcionários

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

▶ Exemplo: Gestão de arquivos de funcionários

R 📖 Somente leitura
# ============================================
# Employee File Management
# Features:Manage with Lists 3 Complete information about each employee
# ============================================

# 1. Create 3 List of employees
employees <- list(
  alice = list(
    id = 2024001,
    name = "Alice",
    department = "Data Analysis Department",
    salary = 15000,
    skills = c("R", "Python", "SQL"),
    projects = c("User Profiles", "Sales Forecast")
  ),
  bob = list(
    id = 2024002,
    name = "Bob",
    department = "Engineering Department",
    salary = 18000,
    skills = c("Java", "Go", "Docker"),
    projects = c("API Refactoring", "Microservice Migration")
  ),
  charlie = list(
    id = 2024003,
    name = "Charlie",
    department = "Product Department",
    salary = 20000,
    skills = c("Figma", "Axure"),
    projects = c("V2.0 Design", "User Research")
  )
)

# 2. View a specific employee's full profile
cat("=== Alice Full Information ===\n")
str(employees$alice)
# List of 6
#  $ id         : num 2024001
#  $ name       : chr "Alice"
#  $ department : chr "Data Analysis Department"
#  $ salary     : num 15000
#  $ skills     : chr [1:3] "R" "Python" "SQL"
#  $ projects   : chr [1:2] "User Profiles" "Sales Forecast"

# 3. Use sapply for batch processing
cat("\n=== Annual Salaries of All Employees ===\n")
annual_salaries <- sapply(employees, function(emp) emp$salary * 12)
print(annual_salaries)
#    alice      bob  charlie 
#   180000   216000   240000

# 4. Use sapply to count skills
cat("\n=== Number of skills per employee ===\n")
skill_counts <- sapply(employees, function(emp) length(emp$skills))
print(skill_counts)
#    alice      bob  charlie 
#        3         3         2

# 5. Use split for grouping by department
cat("\n=== Grouped by Department ===\n")
dept_groups <- split(
  sapply(employees, function(emp) emp$name),
  sapply(employees, function(emp) emp$department)
)
print(dept_groups)
# $Data Analysis Department
# [1] "Alice"
# 
# $Engineering Department
# [1] "Bob"
# 
# $Product Department
# [1] "Charlie"

# 6. Add a New Employee
employees$diana <- list(
  id = 2024004,
  name = "Diana",
  department = "Data Analysis Department",
  salary = 16000,
  skills = c("R", "Tableau"),
  projects = c("Data Visualization")
)

cat("\n=== Add Diana after ===\n")
cat("Total Number of Employees:", length(employees), "\n")
cat("Diana Department:", employees$diana$department, "\n")

# 7. Identify the employee with the highest salary
top_salary <- which.max(sapply(employees, function(emp) emp$salary))
cat("\nHighest Salary:", names(employees)[top_salary], "(", max(sapply(employees, function(emp) emp$salary)), "USD)\n")

# 8. Retrieve the skills of all employees(Merge all skill vectors)
all_skills <- unlist(lapply(employees, function(emp) emp$skills))
cat("\n=== Company-wide Skills Summary ===\n")
print(table(all_skills))
# all_skills
#   Axure  Docker    Figma      Go    Java   Python       R     SQL Tableau 
#       1       1       1       1       1       1       2       1       1
56 linhas de lógica (limite de 40, somente leitura)

Resultado esperado (trecho):

TEXT 📖 Somente leitura
=== Alice Full Information ===
List of 6
 $ id         : num 2024001
 $ name       : chr "Alice"
 ...

=== Annual Salaries of All Employees ===
   alice      bob  charlie 
  180000   216000   240000 

=== Company-wide Skills Summary ===
all_skills
  Axure  Docker  Figma      Go   Java  Python     R   SQL Tableau 
      1       1       1       1       1       1       2       1       1 

❓ Perguntas Frequentes

P: Qual é a diferença entre [[ ]] e [ ]? R: [[ ]] retorna o próprio elemento (que pode ser manipulado posteriormente), enquanto [ ] retorna uma sublista (cujos elementos não podem ser manipulados posteriormente). Use [[ ]] ou $ para recuperar elementos e [ ] para recuperar subconjuntos. Esse é um dos aspectos mais confusos da sintaxe do R.

P: $ e [[ "name" ]] são a mesma coisa? R: Eles são essencialmente equivalentes. No entanto, $ suporta correspondência parcial ($na faz a correspondência automática com “name”), enquanto [[ ]] não. É mais seguro usar [[ "name" ]] em código de produção.

P: Qual é a relação entre listas e vetores? R: Os vetores são homogêneos e unidimensionais (todos os elementos são do mesmo tipo), enquanto as listas são heterogêneas e podem ter qualquer dimensão (os elementos podem ser de qualquer tipo). data.frame Em essência, uma lista é uma “lista de vetores de comprimento igual” — compreender listas significa compreender data frames.

P: Como faço para escolher entre lapply() e sapply()? R: lapply() retorna uma lista (preservando a estrutura), enquanto sapply() simplifica o resultado para um vetor ou matriz (tornando-o mais fácil de ler). Use sapply para tarefas cotidianas e lapply para pipelines de programação funcional.

P: unlist() Quando isso deve ser usado? R: Para “transformar” uma lista em um vetor — mas apenas elementos atômicos podem ser transformados. Tipos mistos serão convertidos (por exemplo, list(1, "a") → c("1", "a")).


📖 Resumo


📝 Exercícios

  1. Exercício Básico: Crie uma lista chamada student contendo quatro campos: name (caractere), age (número), scores (vetor de valores c(85, 90, 92)) e passed (booleano). Imprima a estrutura da lista (str()) e acesse name e scores[2].

  2. Problema básico: Crie uma lista aninhada family contendo três sublistas father, mother e child (cada uma delas contendo name e age). Acesse child$age e imprima-o.

  3. Problema básico: Use lapply() para calcular em lote o “salário anual” (salary * 12) de uma lista de três funcionários (que você mesmo criará) e use sapply() para simplificar os resultados em um vetor de saída.

  4. Problema avançado: Escreva uma função create_employee(name, dept, salary) que retorne uma lista nomeada (contendo id, nome, departamento, salário, habilidades = vetor vazio, is_active = TRUE). Chame-a três vezes para criar três funcionários e armazene-os em uma lista grande. Use sapply() para extrair o “salário anual” de todos os funcionários.

  5. Desafio: Escreva um script para simular a gestão de uma “biblioteca”: ① Crie uma lista library contendo 3 livros (cada livro possui 4 campos: title, author, year e available); ② Use lapply para definir o valor de available de todos os livros como FALSE (retirados); ③ Use sapply para encontrar todos os livros disponíveis para empréstimo (available == TRUE); ④ Adicione um novo livro à lista.

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%