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.csv e o método do tidyverse readr, 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



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:

TEXT 📖 Somente leitura
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

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

TEXT 📖 Somente leitura
Name,Age,City
Alice,25,Beijing
Bob,30,Shanghai
Charlie,35,Guangzhou

(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
100%
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

100%
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

R
# 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
💡 Dica: Use 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

R
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

R
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
R
# 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

R
write_csv(x, file, na = "NA", append = FALSE, col_names = TRUE)

(2) Aplicação prática

R
# 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:

R
# Write
write_csv(sales, "sales.csv")

# Read it again
sales_loaded <- read_csv("sales.csv")
# Type by read_csv Re-inference
💡 Dica: Use .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

R
# 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

R
# 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

R
# 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

R
# 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()

R
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)

R
# 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

R 📖 Somente leitura
# ============================================
# 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))
57 linhas de lógica (limite de 40, somente leitura)

Resultado esperado (trecho):

TEXT 📖 Somente leitura
=== 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.csv e read_csv? R: Para novos projetos, use read_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, use read.csv combinado com stringsAsFactors = 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, use spec(df) para visualizar os resultados da inferência e, em seguida, use type_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 primeiro guess_encoding() para verificar.

P: Como faço para ler um arquivo CSV de 1 GB? R: 3 etapas de otimização: ① col_select Leia apenas as colunas necessárias ② col_types Ignore as colunas desnecessárias ③ Desative progress = FALSE. Se ainda estiver lento, use data.table::fread (mais rápido).

P: O que devo fazer se o write_csv nã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 o saveRDS() / 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_csv e fread? 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 pacote data.table. Para a maioria dos projetos, o read_csv é suficiente.


📖 Resumo


📝 Exercícios

  1. Exercício básico: Crie um tibble contendo 5 linhas e 4 colunas (id/nome/pontuação/data). Use write_csv() para gravar em test.csv e, em seguida, use read_csv() para ler os dados de volta e verifique se a inferência de tipo está correta (date é do tipo Data).

  2. Exercício básico: Leia o test.csv da questão anterior, use o col_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.

  3. Exercício básico: Crie um data frame contendo valores NA (usando c(1, NA, 3, NA, 5)), exporte-o para CSV, leia-o usando na = c("NA", "") e verifique se os valores NA foram tratados corretamente.

  4. 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; ③ Use read_csv para gerar dois relatórios: top5.csv e by_region.csv.

  5. 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 usando read_csv e read_delim, respectivamente, e compare as diferenças nos resultados. Faça uma captura de tela da saída do console e salve-a.

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%