readr read_delim() in R: Read Any Delimited Text File
The readr read_delim() function reads a text file with any single-character delimiter into a tibble. You set the separator with the delim argument, so pipe, semicolon, and tab files all parse with one function.
read_delim("data.txt", delim = "|") # pipe-delimited file
read_delim("data.txt", delim = ";") # semicolon-delimited file
read_delim("data.txt", delim = "\t") # tab-delimited file
read_delim(I("a;b\n1;2"), delim = ";") # read delimited text directly
read_delim("data.txt", delim = "|", col_select = c(a, b)) # keep only some columns
read_delim("data.txt", delim = "|", skip = 2) # skip junk header rows
read_delim("data.txt", delim = "|", na = c("", "NA", "-"))# set the NA stringsNeed explanation? Read on for examples and pitfalls.
What read_delim() does
read_delim() reads a delimited text file into a tibble. You give it a file path, a URL, or literal text, plus the delim character that separates fields. It scans the first rows to guess each column type, then parses the whole file in fast C++ code and returns a tidy data frame.
It is the general-purpose reader in the readr family. read_csv() and read_tsv() are just read_delim() with the delimiter fixed to a comma or a tab. When your file uses any other separator, reach for read_delim() and set delim yourself.
Syntax and key arguments
The signature is compact, and delim is the argument that defines the call. Most reads only need file and delim; the rest tune parsing.
When delim is NULL, read_delim() tries to guess the separator. The guess is usually right for clean files, but passing delim explicitly is safer and documents the format for the next reader.
read_delim("data.txt", delim = "|") is pandas.read_csv("data.txt", sep="|"). The pandas sep argument maps to readr's delim, and usecols maps to col_select.read_delim() examples
Start with a round trip. Write a built-in dataset to a pipe-delimited file, then read it back so every example has a real file to use.
The column specification message confirms the delimiter and how each field parsed. All 11 columns came back as dbl (double).
You can read delimited text directly without a file. Wrap the literal string in I() so read_delim() treats it as data, not a path.
Read only the columns and rows you need. col_select accepts unquoted names and n_max caps the row count, which keeps large files cheap to explore.
Declare your own missing-value markers. Real exports use codes like n/a or -. Pass them to na so they parse as NA instead of forcing a column to text.
col_types skips the guessing scan, silences the spec message, and guarantees stable types across files. Use cols(cyl = col_integer(), .default = col_double()) to set one column and default the rest.read_delim() vs read_csv() and read_tsv()
read_delim() is the general reader; read_csv() and read_tsv() are shortcuts. They share the same engine, so the choice is about how much you spell out.
| Function | Delimiter | When to use |
|---|---|---|
read_delim() |
any, set via delim |
pipe, semicolon, or any custom separator |
read_csv() |
comma, fixed | standard comma-separated files |
read_tsv() |
tab, fixed | tab-separated files |
read_csv2() |
semicolon, fixed | EU files: ; separator, , decimal |
read_table() |
whitespace | space-aligned columns with ragged spacing |
Use read_csv() or read_tsv() when the format is standard; the name documents the file. Use read_delim() for everything else, and for EU semicolon files prefer read_csv2() because it also handles the comma decimal mark.
read_delim() and change one argument. The delim value is the only thing that varies between a pipe file, a semicolon file, and a tab file.Common pitfalls
Relying on delimiter guessing. When you omit delim, read_delim() guesses the separator from the first lines. A file with commas inside quoted text can fool the guess. Always pass delim explicitly.
Passing a multi-character delimiter. The delim argument takes exactly one character. A string like "||" or ", " raises an error. For fixed-width files with no separator, use read_fwf() instead.
Trusting guessed types on messy columns. read_delim() guesses types from the first 1,000 rows. If a clean numeric column has stray text far down, the column reads as character. Set col_types explicitly when a column matters.
Try it yourself
Try it: Write mtcars to a semicolon-delimited file, read it back keeping only mpg and cyl, then count the rows where cyl equals 4. Save the count to ex_count.
Click to reveal solution
Explanation: delim = ";" matches the separator used by write_delim(). col_select keeps just the two columns, and sum() over a logical vector counts the TRUE values, giving the number of 4-cylinder cars.
Related readr functions
read_delim() sits at the center of the readr import family. Reach for the sibling that matches your file format.
read_csv(): read comma-separated files.read_tsv(): read tab-separated files.read_csv2(): read semicolon-separated European CSV files.read_fwf(): read fixed-width files that have no delimiter.write_delim(): write a data frame back out with any delimiter.
For the full argument reference, see the readr read_delim documentation on tidyverse.org.
FAQ
What is the difference between read_delim() and read_csv() in R?
read_delim() reads a file with any single-character delimiter, which you set through the delim argument. read_csv() is a shortcut with the delimiter fixed to a comma. Both use the same fast parser and return a tibble. Use read_csv() when the file is standard CSV, and read_delim() when the separator is a pipe, semicolon, or anything else.
How do I read a pipe-delimited file in R?
Call read_delim("data.txt", delim = "|"). The delim argument tells readr that the vertical bar separates fields, and the function returns a tibble with one column per field. The same pattern works for any single character, so a tilde file uses delim = "~".
How do I read a tab-delimited file with read_delim()?
Pass the tab escape sequence as the delimiter: read_delim("data.txt", delim = "\t"). This is exactly what read_tsv() does internally, so read_tsv("data.txt") is the shorter equivalent. Use whichever reads more clearly in your script.
Why does read_delim() guess the wrong column types?
read_delim() guesses each type from the first 1,000 rows. If a column looks numeric early but contains text further down, the guess can be wrong. Fix it by passing col_types, for example col_types = cols(score = col_character()), which overrides the guess for that column.
Can read_delim() read a file from a URL?
Yes. Pass an http:// or https:// URL as the file argument and read_delim() downloads and parses it in one step. For a file you will reuse, download it once with download.file() and read the local copy to avoid repeated network calls.