R: Leitura e gravação de arquivos CSV
Última atualização: 2026-08-26
Nas primeiras 10 aulas, nos concentramos nos dados dentro do R, mas, em projetos do mundo real, 99% dos dados estão armazenados em arquivos externos. Nesta aula, aprenderemos sobre o formato de dados mais utilizado — arquivos CSV. O R oferece duas maneiras de ler e gravar arquivos CSV: o método padrão do R
read.csve o método do tidyversereadr, sendo que o último é mais inteligente e mais rápido.
Ao concluir esta lição, você será capaz de carregar 1.000 linhas de dados de vendas no R em 5 segundos e gerar relatórios bem organizados.
1. O que você vai aprender
- O que é um arquivo CSV e por que ele é usado na ciência de dados?
- A diferença entre o R básico
read.csve o tidyversereadr read_csv()8 parâmetros comuns (col_types, na, skip, n_max, etc.)write_csv()Gerar relatório- Tratamento de problemas comuns (codificação, valores ausentes, delimitadores)
- Dicas para a leitura de arquivos grandes (divisão em blocos, otimização de tipos)
2. Um desafio na importação de dados
(1) Problema: a conversão do Excel para o R faz com que o sistema trave
Chen é analista, e seu gerente lhe enviou um arquivo CSV de 100 MB contendo dados de vendas:
id,date,product,region,amount
1,2024-01-15,Cell Phone,Beijing,2999
2,2024-01-15,Computer,Shanghai,5999
3,2024-01-16,Cell Phone,Guangzhou,2899
...
(@,000 rows of)
Ele leu os dados usando read.csv(), esperou 30 segundos e levou mais 10 segundos para imprimir @.000 linhas de. Ele também descobriu que todas as cinco colunas eram do tipo chr (números tratados como strings).
(2) Solução utilizando R
# 1. Use readr Smart Reading(5 s)
library(readr)
sales <- read_csv("sales.csv")
# 2. Automatic Type Inference
# id → integer, date → date, product → character,
# region → character, amount → double
# 3. Read only the rows you need(Speed Up 3x)
sales_sample <- read_csv("sales.csv", n_max = 10000)
# 4. Write clean reports
write_csv(sales_sample, "sales_clean.csv")
1 linha de código = 30 segundos → 5 segundos. Esse é o poder do readr.
3. O que é CSV?
(1) CSV = Valores separados por vírgulas
Name,Age,City
Alice,25,Beijing
Bob,30,Shanghai
Charlie,35,Guangzhou
- Cada linha = 1 registro
Separe os campos com
,(ou;|\t). - A primeira linha geralmente contém os nomes das colunas (cabeçalho)
- Suporta aspas em strings
"..."para o tratamento de campos que contêm vírgulas
(2) Por que o CSV é tão amplamente utilizado na ciência de dados?
| Vantagens | Descrição |
|---|---|
| Geral | Compatível com Excel, Python, R e bancos de dados |
| Legível por humanos | Pode ser visualizado diretamente no Bloco de Notas |
| Tamanho reduzido do arquivo | 5 a 10 vezes menor que o Excel |
| Multiplataforma | Sem caracteres distorcidos devido a versões diferentes do Excel |
| Fácil de usar | Sem formatação do Excel nem confusão com fórmulas |
graph LR
A[CSV Documents<br/>name,age,city] --> B[read_csv Smart Reading]
B --> C[tibble Clean DataFrame]
C --> D[write_csv Reports]
C --> E[dplyr Analysis]
C --> F[ggplot2 Visualization]
style A fill:#cce5ff
style B fill:#d4edda
style C fill:#fff3cd
style D fill:#f8d7da
style E fill:#e1d4ff
style F fill:#ffe1d4
4. R básico x tidyverse: duas abordagens para trabalhar com arquivos CSV
mindmap
root((CSV Read/write<br/>Two Options))
Basics R
read.csv
write.csv
Slow
String Conversion factor
tidyverse
readr
read_csv
write_csv
read_tsv
Advantages
Intelligent Type Inference
Fast 5-10x
Large File Progress Bar
Strings are not converted factor
Selection Recommendations
New Project: tidyverse
Legacy code: read.csv + stringsAsFactors = FALSE
GB Level data: data.table::fread
(1) Comparação entre as duas abordagens
| Recurso | Base R read.csv |
tidyverse read_csv |
|---|---|---|
| Velocidade | Lenta (compatível com R) | 5 a 10 vezes mais rápida (backend em C++) |
| Inferência de tipo | Fraca (padrão: chr) | Inferência inteligente (int/dbl/date/lgl) |
| Barra de progresso | ❌ | ✅ (Funciona bem com arquivos grandes) |
| String | Converter em fator por padrão | Manter como string |
| Tipo de retorno | data.frame | tibble (mais intuitivo) |
| Processamento de listas | Tolerância a erros | Limpeza automática (espaços, caracteres especiais) |
| Valor ausente | NA |
NA + string personalizada |
| String | stringsAsFactors = TRUE |
Sempre FALSE |
(2) Comparação real
# Basics R(Common Issues with Legacy Code)
df_old <- read.csv("data.csv")
# Default behavior:Convert all string arrays factor(Pitfall!)
# tidyverse(Recommendations)
library(readr)
df_new <- read_csv("data.csv")
# Intelligent Inference Types,Character retains character
readr para todos os novos projetos; para código legado, use read.csv followed by stringsAsFactors = FALSE.
(3) Quando se deve usar o R básico?
| Cenário | Recomendação |
|---|---|
| Novo projeto / Escrever novo código | read_csv (readr) |
| Processamento de conjuntos de dados massivos na escala de GB | data.table::fread (Mais rápido) |
| Manutenção de código legado | read.csv e stringsAsFactors = FALSE |
| Tutorial / Script simples | Qualquer um dos dois |
5. 8 parâmetros comuns da função read_csv()
(1) Sintaxe básica
read_csv(file, col_types = TRUE, col_names = TRUE, na = "NA",
skip = 0, n_max = Inf, locale = default_locale(),
progress = TRUE)
(2) Tabela de referência rápida de parâmetros
| Parâmetro | Função | Valor padrão |
|---|---|---|
file |
Caminho do arquivo ou URL | Obrigatório |
col_types |
Especificação do tipo da coluna | TRUE (inferido automaticamente) |
col_names |
TRUE/Vector (nome da coluna personalizada) | TRUE (usar a primeira linha) |
na |
Marcador de valor ausente | "NA" |
skip |
Ignorar as primeiras N linhas | 0 |
n_max |
Número máximo de linhas a serem lidas | Inf (todas) |
locale |
Configurações regionais (codificação, ponto decimal) | default_locale() |
progress |
Mostrar barra de progresso | TRUE |
(3) Prática: Parâmetros comuns
library(readr)
# 1. Basic Reading(Intelligent Inference Types)
df <- read_csv("data.csv")
# 2. Specify Column Type(Avoiding Fallacies in Reasoning)
df <- read_csv("data.csv", col_types = cols(
id = col_integer(),
date = col_date(format = "%Y-%m-%d"),
amount = col_double(),
name = col_character()
))
# 3. Skip to the beginning 5 Line Comments
df <- read_csv("data.csv", skip = 5)
# 4. Custom NA Mark(CSV For internal use "NULL" Indicates missing)
df <- read_csv("data.csv", na = c("", "NA", "NULL", "N/A"))
# 5. Read-only before 1000 row(For debugging purposes)
df <- read_csv("data.csv", n_max = 1000)
# 6. Skip Column(Use col_types Set as col_skip())
df <- read_csv("data.csv", col_types = cols(
temp_col = col_skip()
))
(4) Uma explicação detalhada sobre a inferência inteligente de tipos
A maior vantagem do readr é a inferência automática:
| Dados de amostra | Inferido como |
|---|---|
1, 2, 3 |
integer |
1.5, 2.3 |
double |
2024-01-15 |
date |
12:30:00 |
time |
TRUE, FALSE |
logical |
Beijing, Shanghai |
character |
# Examples of Inference
sales <- read_csv("sales.csv")
spec(sales) # View the inference results
# cols(
# id = col_integer(),
# date = col_date(format = "%Y-%m-%d"),
# product = col_character(),
# region = col_character(),
# amount = col_double()
# )
6. write_csv(): Gera um relatório
(1) Sintaxe básica
write_csv(x, file, na = "NA", append = FALSE, col_names = TRUE)
(2) Aplicação prática
# 1. Basic Output
write_csv(sales, "sales_clean.csv")
# 2. Output to the specified path
write_csv(sales, "output/2024_sales.csv")
# 3. Append to the existing file(Do not cover)
write_csv(new_data, "sales.csv", append = TRUE, col_names = FALSE)
# 4. Custom NA indicates
write_csv(df, "output.csv", na = "")
(3) ⚠️ write_csv não preserva os tipos de dados
Quando o readr grava em CSV, as informações de tipo são perdidas (já que o CSV é texto simples). Ao ler o arquivo novamente, os tipos devem ser inferidos novamente:
# Write
write_csv(sales, "sales.csv")
# Read it again
sales_loaded <- read_csv("sales.csv")
# Type by read_csv Re-inference
.rds para persistência interna no R (preservação de tipos) — consulte a Lição 12.
7. Resolução de problemas comuns
(1) Caracteres chineses distorcidos
# 1. Read Using a Specified Encoding
df <- read_csv("data.csv", locale = locale(encoding = "UTF-8"))
# Or
df <- read_csv("data.csv", locale = locale(encoding = "GBK"))
# 2. Check the file encoding
guess_encoding("data.csv")
# Returns in most cases "UTF-8" or "GBK"
# 3. Specify the encoding when writing
write_csv(df, "output.csv") # Default UTF-8
(2) O delimitador não é uma vírgula
# 1. Tab-separated(TSV)
df <- read_tsv("data.tsv") # sep = "\t"
# 2. Semicolon-separated(Commonly Used in Europe)
df <- read_csv2("data.csv") # sep = ";"
# 3. Custom Delimiters(e.g. |)
df <- read_delim("data.txt", delim = "|")
(3) Números com separadores de milhares
# European Format:1.234,56(A percentile is .,A decimal is ,)
df <- read_csv("data_eu.csv",
locale = locale(grouping_mark = ".", decimal_mark = ","))
(4) Leitura lenta de arquivos grandes
# 1. Read only the required columns(Speed Up 2-3x)
df <- read_csv("big.csv", col_select = c(id, amount))
# 2. Use col_types Skip Column
df <- read_csv("big.csv", col_types = cols(
temp_col_1 = col_skip(),
temp_col_2 = col_skip()
))
# 3. Close the progress bar
df <- read_csv("big.csv", progress = FALSE)
# 4. A Faster Solution:data.table::fread
# fread("big.csv") is 5-10x faster than read_csv
8. Avançado: Especificação do tipo de coluna cols()
(1) Sintaxe completa da função cols()
col_types = cols(
id = col_integer(), # Integer
name = col_character(), # Character
amount = col_double(), # Double-precision floating-point
date = col_date(), # Date
time = col_time(), # Time
datetime = col_datetime(),# Date and Time
is_active = col_logical(),# Logic
skip = col_skip(), # Skip this column
guess = col_guess() # Let readr infer
)
(2) Notação abreviada para strings (mais concisa)
# Use "i" "c" "d" "D" "l" Abbreviation
col_types = cols(
id = "i", # integer
name = "c", # character
amount = "d", # double
date = "D", # date
is_active = "l" # logical
)
# All Inferences(Default)
col_types = TRUE
# Using a list(Sequence-Mapped Columns)
col_types = list(
id = col_integer(),
name = col_character()
)
9. Exemplo completo: importação e análise de dados de vendas
A seguir, apresentamos um exemplo de um fluxo de trabalho completo que reúne todos os conceitos abordados nesta aula.
▶ Exemplo: Importação de dados de vendas + Limpeza de dados + Geração de relatórios
# ============================================
# Importing and Processing Sales Data
# Features:Read CSV → Cleaning → Analysis → Generate Report
# ============================================
library(readr)
library(dplyr)
# 1. Preparing Sample Data
sample_data <- tibble(
id = 1:10,
date = as.Date("2024-01-01") + 0:9,
product = c("Cell Phone", "Computer", "Cell Phone", "Tablet", "Cell Phone",
"Computer", "Tablet", "Cell Phone", "Computer", "Cell Phone"),
region = c("Beijing", "Shanghai", "Guangzhou", "Beijing", "Shenzhen",
"Shanghai", "Guangzhou", "Beijing", "Shenzhen", "Shanghai"),
amount = c(2999, 5999, 2899, 3999, 3099,
6299, 3899, 2899, 5999, 3199),
note = c(NA, "Promo", NA, NA, "New Products", NA, NA, "Promo", NA, NA)
)
# Write Example CSV(UTF-8 Coding)
write_csv(sample_data, "sales_demo.csv")
cat("=== The file has been generated ===\n")
# 2. Read CSV(Intelligent Inference)
sales <- read_csv("sales_demo.csv",
na = c("", "NA"),
col_types = cols(
id = col_integer(),
date = col_date(format = "%Y-%m-%d"),
product = col_character(),
region = col_character(),
amount = col_double(),
note = col_character()
))
cat("=== Read the results ===\n")
print(sales)
# 3. Data Quality Check
cat("\n=== Data Structures ===\n")
str(sales)
# 4. Data Analysis
cat("\n=== Sales Statistics ===\n")
summary_stats <- sales |>
group_by(region) |>
summarise(
Number of Orders = n(),
Total Sales = sum(amount),
Average Order = round(mean(amount), 2),
Highest Order = max(amount)
) |>
arrange(desc(Total Sales))
print(summary_stats)
# 5. Find promotional orders
cat("\n=== Promotional Orders ===\n")
promo <- sales |> filter(!is.na(note))
print(promo)
# 6. By Product Category
cat("\n=== Product Sales ===\n")
product_stats <- sales |>
group_by(product) |>
summarise(Sales = n(), Sales = sum(amount))
print(product_stats)
# 7. Generate clean reports
write_csv(summary_stats, "sales_by_region.csv")
write_csv(product_stats, "sales_by_product.csv")
cat("\n=== The report has been generated ===\n")
cat(" - sales_by_region.csv(By Region)\n")
cat(" - sales_by_product.csv(By Product)\n")
# 8. Use RDS Reserved Types(Recommendations)
saveRDS(sales, "sales_clean.rds")
sales_reloaded <- readRDS("sales_clean.rds")
cat("\nRDS Type After Loading:\n")
print(sapply(sales_reloaded, class))
Resultado esperado (trecho):
=== Sales Statistics ===
# A tibble: 4 × 5
region Number of Orders Total Sales Average Order Highest Order
<chr> <int> <dbl> <dbl> <dbl>
1 Beijing 3 9897 3299 3999
2 Shanghai 3 15497 5166. 6299
3 Guangzhou 2 6798 3399 3899
4 Shenzhen 2 9098 4549. 5999
=== Promotional Orders ===
# A tibble: 2 × 6
id date product region amount note
<int> <date> <chr> <chr> <dbl> <chr>
1 2 2024-01-02 Computer Shanghai 5999 Promo
2 8 2024-01-08 Cell Phone Beijing 2899 Promo
❓ Perguntas Frequentes
P: Como faço para escolher entre
read.csveread_csv? R: Para novos projetos, useread_csv(tidyverse) — ele é de 5 a 10 vezes mais rápido, infere tipos de dados de forma inteligente e é compatível com tibbles. Para códigos já existentes, useread.csvcombinado comstringsAsFactors = FALSE.
P: O que devo fazer se o tipo do CSV for inferido incorretamente? R: Use
col_types = cols(...)para especificar explicitamente o tipo. Após ler o arquivo, usespec(df)para visualizar os resultados da inferência e, em seguida, usetype_convert()ou releia o arquivo para corrigi-lo.
P: Os caracteres chineses aparecem distorcidos ao ler um arquivo CSV? R: Use
locale = locale(encoding = "UTF-8")ou"GBK". Se você não tiver certeza da codificação, tente primeiroguess_encoding()para verificar.
P: Como faço para ler um arquivo CSV de 1 GB? R: 3 etapas de otimização: ①
col_selectLeia apenas as colunas necessárias ②col_typesIgnore as colunas desnecessárias ③ Desativeprogress = FALSE. Se ainda estiver lento, usedata.table::fread(mais rápido).
P: O que devo fazer se o
write_csvnão conseguir salvar o tipo de dados? R: O CSV é um formato de texto simples que, por definição, não armazena tipos de dados. O R utiliza osaveRDS()/readRDS()para persistência interna — o que preserva os tipos de dados e é mais rápido (mais nativo do R).
P: Como faço para escolher entre
read_csvefread? R:read_csvé o padrão no tidyverse e se integra bem com o dplyr e o ggplot2;freadé mais rápido (a opção preferida para dados na escala GB), mas requer a instalação do pacotedata.table. Para a maioria dos projetos, oread_csvé suficiente.
📖 Resumo
- O CSV é o formato de dados mais versátil: texto simples, legível por pessoas, compatível com várias plataformas e compatível com o Excel, Python, R e bancos de dados
- Recomendado:
readr::read_csv— 5 a 10 vezes mais rápido que o R básicoread.csv, com inferência inteligente de tipos e compatibilidade com o Tibble - 8 parâmetros comumente utilizados:
col_types(especificação do tipo),na(indicador NA),skip,n_max,col_select,locale,progress,col_names - Inferência automática de tipos: inteiro / duplo / data / hora / data-hora / booleano / string
write_csv()Gera um relatório, mas não preserva o tipo de dados — usesaveRDS()/readRDS()para persistência interna no R- Use
locale = locale(encoding = "UTF-8")para caracteres chineses distorcidos; se o separador não for,, useread_tsvouread_delim - Otimização de arquivos grandes:
col_select+col_types = col_skip()+ desativar a barra de progresso
📝 Exercícios
-
Exercício básico: Crie um
tibblecontendo 5 linhas e 4 colunas (id/nome/pontuação/data). Usewrite_csv()para gravar emtest.csve, em seguida, useread_csv()para ler os dados de volta e verifique se a inferência de tipo está correta (dateé do tipo Data). -
Exercício básico: Leia o
test.csvda questão anterior, use ocol_types = cols()para especificar explicitamente os tipos de todas as colunas (id: inteiro, score: duplo, name: string, date: data) e verifique se os tipos correspondem às especificações explícitas. -
Exercício básico: Crie um data frame contendo valores NA (usando
c(1, NA, 3, NA, 5)), exporte-o para CSV, leia-o usandona = c("NA", "")e verifique se os valores NA foram tratados corretamente. -
Exercício avançado: Simule 100 linhas de dados de vendas (produto/região/valor/data). Após importar os dados usando
read_csv: ① Calcule o total de vendas por região; ② Identifique os 5 pedidos com os valores mais altos; ③ Useread_csvpara gerar dois relatórios:top5.csveby_region.csv. -
Desafio: Crie um arquivo CSV contendo caracteres especiais (nomes de colunas com espaços, sequências de caracteres contendo vírgulas e o separador
|), leia-o usandoread_csveread_delim, respectivamente, e compare as diferenças nos resultados. Faça uma captura de tela da saída do console e salve-a.