Real work starts with data in files, and import options decide whether your columns come in right.
Base R reads delimited text with read.csv(path) (comma-separated, header row) and read.delim (tabs); read.table is the general version. Useful arguments: na.strings = c("", "NA") for how missing values are written, colClasses to force column types, skip and nrows. Write with write.csv(df, path, row.names = FALSE); without row.names = FALSE you get an extra unnamed column.
readRDS/saveRDS store any single R object in R's binary format, preserving types and factors exactly; use them for intermediate results.
In practice most people use packages:
- readr (
read_csv) is faster, returns a tibble, never converts strings to factors, and reports column types it guessed. - data.table's
freadis extremely fast on large files and guesses separators. - readxl reads Excel files, haven SPSS/Stata/SAS, arrow Parquet, and DBI talks to databases.
Paths are relative to the working directory (getwd()); rather than setwd() in scripts, use project-relative paths (RStudio projects or the here package).
After importing, always check: str(df) for types, summary(df) for ranges and NA counts. A numeric column that came in as character usually means a stray value like "n/a" or "1,234".
Example
path <- tempfile(fileext = ".csv")
writeLines(c("id,city,temp", "1,Yerevan,31.5", "2,Gyumri,n/a", "3,Dilijan,24"), path)
df <- read.csv(path)
print(class(df$temp)) #> [1] "character" (because of n/a)
df <- read.csv(path, na.strings = c("", "n/a"))
str(df)
#> 'data.frame': 3 obs. of 3 variables:
#> $ id : int 1 2 3
#> $ city: chr "Yerevan" "Gyumri" "Dilijan"
#> $ temp: num 31.5 NA 24
out <- tempfile(fileext = ".csv")
write.csv(df[!is.na(df$temp), ], out, row.names = FALSE)
print(readLines(out)[1:2]) #> [1] "\"id\",\"city\",\"temp\"" "1,\"Yerevan\",31.5"
rds <- tempfile(fileext = ".rds")
saveRDS(df, rds)
print(identical(readRDS(rds), df)) #> [1] TRUERemember
read.csv+na.strings/colClassesfor control over parsingwrite.csv(..., row.names = FALSE)avoids an extra columnsaveRDS/readRDSround-trip any R object exactly- Always check
str()right after importing
Watch out for
- A single odd value such as "n/a" turning a whole numeric column into character.