0Pricing
R Academy · Lesson

Reading CSV Files with read_csv()

Import delimited files with column type guessing, skipping, and encoding options.

Reading CSV Files with read_csv() is a free R Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the R Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why readr Instead of Base R?

Base R has read.csv(), but the readr package's read_csv() is faster, returns a tibble (not a data frame), provides better default type guessing, and gives informative messages about the column types it detected.

library(readr)

# read_csv() vs read.csv():
# 1. Returns a tibble (prints nicely, faster subsetting)
# 2. Does NOT convert strings to factors by default
# 3. Shows column specification message
# 4. Faster for large files

# Example with a simple inline CSV:
df <- read_csv('name,score,grade
Alice,85,B
Bob,92,A
Carol,78,C')

print(df)
print(class(df))

read_csv() from a File Path

The most common usage: pass a file path string to read_csv(). The function automatically detects the delimiter as a comma, reads the first row as headers, and guesses column types from the first 1000 rows.

library(readr)

# Reading from a file path (illustrative — file not present)
# df <- read_csv('data/sales_2024.csv')

# Reading from a URL also works:
# df <- read_csv('https://example.com/data.csv')

# Using a literal inline string for demonstration:
df <- read_csv('region,q1,q2,q3
East,100,120,115
West,200,195,210
North,80,85,90')

print(df)

col_types — Specifying Column Types

Use col_types to override readr's type guessing. Pass a compact string (one character per column: c=character, d=double, i=integer, l=logical, D=date, _=skip) or a cols() specification.

library(readr)

df <- read_csv('id,date,amount,active
1,2024-01-15,99.99,TRUE
2,2024-02-20,149.50,FALSE
3,2024-03-10,75.00,TRUE',
# Compact: integer, Date, double, logical
col_types = 'iDdl')

print(df)
cat('\nColumn types:\n')
print(sapply(df, class))

cols() for Explicit Type Specification

For more control, use cols() to name each column's type. Use collector functions: col_double(), col_character(), col_integer(), col_date(format=), col_skip(), and col_guess().

library(readr)

df <- read_csv('id,name,score,date
1,Alice,85.5,2024-01-15
2,Bob,92.0,2024-02-20
3,Carol,78.3,2024-03-10',
col_types = cols(
  id = col_integer(),
  name = col_character(),
  score = col_double(),
  date = col_date(format = '%Y-%m-%d')
))

print(df)
print(class(df$date))

skip and n_max Arguments

skip=n skips the first n lines before reading (useful for metadata or comment headers). n_max=n reads at most n data rows — perfect for previewing large files or loading only the first chunk.

library(readr)

# File with metadata in first 2 lines
# (simulated with literal string)
df <- read_csv('# Generated 2024-01-15
# Source: internal DB
name,score,grade
Alice,85,B
Bob,92,A
Carol,78,C
Dave,88,B',
skip = 2,     # Skip the 2 comment lines
n_max = 3     # Read only 3 data rows
)

print(df)

na Argument — Defining Missing Values

By default, read_csv() treats empty strings and NA as missing. Use the na argument to specify additional strings that should be read as NA — common examples: 'N/A', 'NULL', '-999', '.'.

library(readr)

df <- read_csv('name,score,city
Alice,85,NYC
Bob,N/A,NULL
Carol,78,.
Dave,-999,Chicago',
na = c('', 'NA', 'N/A', 'NULL', '.', '-999')
)

print(df)
cat('NAs per column:\n')
print(colSums(is.na(df)))

col_names — Custom Column Names

Set col_names = FALSE when the file has no header row — readr will auto-name columns X1, X2, etc. Alternatively, pass a character vector to col_names to specify custom names and skip the header row.

library(readr)

# File without headers
df <- read_csv('Alice,85,NYC
Bob,92,LA
Carol,78,Chicago',
col_names = c('name','score','city')
)

print(df)

# auto-names when no header:
df2 <- read_csv('1,2,3
4,5,6', col_names = FALSE)
print(df2)

locale() — Handling Non-Standard Formats

locale() controls how readr interprets locale-specific formats: decimal marks (',' in European data), date formats, encoding, and grouping marks. Pass it to read_csv(locale=...).

library(readr)

# European-style CSV: semicolons as delimiters, comma as decimal
# read_csv2() is shorthand for this locale
df <- read_csv2('name;price;qty
Alice;9,99;100
Bob;24,50;50',
locale = locale(decimal_mark=',')
)

print(df)

# For dates in non-ISO format:
parse_date('15/01/2024', format='%d/%m/%Y')

progress and show_col_types

For large files, read_csv() shows a progress bar. Set progress=FALSE to suppress it (useful in scripts). show_col_types=FALSE silences the column type message when you've already verified the types.

library(readr)

# Suppress progress and type messages for production scripts
df <- read_csv(
  'a,b,c
  1,x,TRUE
  2,y,FALSE',
  show_col_types = FALSE,
  progress = FALSE
)

print(df)

Problems() — Diagnosing Parse Failures

When readr encounters values that don't match the expected type, it substitutes NA and records a warning. Call problems(df) to inspect exactly which rows and columns had issues and what the original values were.

library(readr)

# Intentional type mismatch: 'N/A' in numeric column
df <- suppressWarnings(read_csv(
  'id,score
  1,85
  2,N/A
  3,92',
  col_types = cols(score = col_double())
))

print(df)
print(problems(df))

Reading Multiple Files with map()

Combine readr with purrr::map() to read and row-bind multiple CSV files in one step. This pattern is essential for processing monthly/quarterly data splits stored as separate files.

library(readr)
library(purrr)
library(dplyr)

# Simulated: read and bind multiple CSV files
files <- c('q1.csv', 'q2.csv', 'q3.csv')

# In practice:
# all_data <- map_df(files, read_csv, show_col_types=FALSE)

# Demonstration with inline data:
q1 <- read_csv('month,sales\nJan,100\nFeb,120', show_col_types=FALSE)
q2 <- read_csv('month,sales\nApr,130\nMay,145', show_col_types=FALSE)

bind_rows(list(q1=q1, q2=q2), .id='quarter')

Quick Check

How do you tell read_csv() that the values 'N/A' and '-99' should be treated as missing (NA)?

Recap: read_csv() with readr

Key takeaways for reading CSV files with readr:

  • read_csv('file.csv') — reads CSV, returns a tibble, guesses column types
  • col_types = 'idcl' or cols(x=col_double()) — explicit type specification
  • skip=n — skip header/metadata rows; n_max=n — limit rows read
  • na = c('N/A','NULL') — treat additional strings as NA
  • locale(decimal_mark=',') — handle European number formats
  • show_col_types=FALSE — suppress type info in scripts
  • problems(df) — inspect parse failures
  • Combine with map_df(files, read_csv) for multiple files
library(readr)

# Production-ready read_csv() call
df <- read_csv(
  'name,score,city,active
  Alice,85,NYC,TRUE
  Bob,N/A,LA,FALSE
  Carol,78,NULL,TRUE',
  col_types = cols(
    name = col_character(),
    score = col_double(),
    city = col_character(),
    active = col_logical()
  ),
  na = c('', 'NA', 'N/A', 'NULL'),
  show_col_types = FALSE
)

print(df)

Frequently asked questions

Is the “Reading CSV Files with read_csv()” lesson free?

Yes — the full text of “Reading CSV Files with read_csv()” is free to read here on the web, and the R Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the R Academy course, upgrade to CoddyKit PRO.

What will I learn in “Reading CSV Files with read_csv()”?

Import delimited files with column type guessing, skipping, and encoding options. You practise R Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start R Academy?

No prior experience is required. R Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Reading CSV Files with read_csv()” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this R Academy lesson?

Yes. Every R Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Reading CSV Files with read_csv()
  2. Parsing TSV and Fixed-Width Files
  3. Importing Excel Files with readxl
  4. Writing Data to Multiple Formats
← Back to R Academy