Module 4: Importing and Exporting Data

Introduction

So far, we have created all of our objects directly inside R.

For example:

stations <- c("CT01", "CT02", "CT03")

detections <- c(12, 5, 8)

But this is not how we normally work with real datasets.

Most of the time, our data already exist in a file created in Excel, Google Sheets, field-data software, or another program.

One of the most important skills when learning R is therefore knowing how to bring external data into R.

In this module we will learn how to:

  • understand where R looks for files,
  • organize data inside an RStudio Project,
  • import .csv files,
  • import Excel files,
  • inspect imported data,
  • and export data from R.
Download the example data

We will use these files throughout this module.

Download CSV

Download Excel

Let’s get started

Open your intro-r-course project and create a new R script.

Save it inside the scripts folder as:

module-04.R

Remember that our project should look approximately like this:

intro-r-course/
│
├── data/
├── scripts/
│   └── module-04.R
├── outputs/
└── intro-r-course.Rproj

Throughout this module, the files we want to import will be stored inside:

data/

Where is R looking for files?

Before importing a file, R needs to know where the file is located.

The folder that R currently considers its starting location is called the working directory.

We can check it using:

getwd()
[1] "C:/Users/andradegp/AppData/Local/Temp/RtmpW8fHyP/file85a434ae5f2c/modules"

Because we are working inside an RStudio Project, the working directory should normally be the main folder of our project:

intro-r-course/

This is one of the main reasons we created an RStudio Project at the beginning of the course.

Avoid using setwd() inside your scripts

You may see tutorials that use:

setwd("C:/Users/YourName/Documents/MyProject")

to specify the working directory.

This may work on your computer, but that path will probably not work on someone else’s computer.

Using an RStudio Project allows us to avoid this problem and work with relative paths instead.

File paths

A file path tells R where a file is located.

There are two general types of paths:

  • absolute paths,
  • relative paths.

Absolute paths

An absolute path describes the complete location of a file on your computer.

For example:

C:/Users/Gabriel/Documents/intro-r-course/data/camera_data.csv

This may work perfectly on one computer.

But if we send the project to another person, their computer probably does not have:

C:/Users/Gabriel/

So the code will no longer work.

Relative paths

A relative path describes the location of a file relative to our project folder.

If our file is stored here:

intro-r-course/
│
├── data/
│   └── camera_data.csv
│
├── scripts/
└── outputs/

we can refer to it simply as:

data/camera_data.csv

This is much more portable.

If we move the entire project to another computer, the internal structure remains the same.

Keep your project organized

A simple project structure such as:

project/
├── data/
├── scripts/
└── outputs/

makes file paths much easier to understand and helps keep your analyses reproducible.

What is a CSV file?

One of the most common formats for storing tabular data is CSV.

CSV stands for:

Comma-Separated Values

A CSV file is essentially a plain-text table.

For example, a spreadsheet that looks like this:

station species detections camera_days
CT01 Raccoon 12 30
CT02 Coyote 5 28
CT03 Bobcat 8 30

may be stored internally as:

station,species,detections,camera_days
CT01,Raccoon,12,30
CT02,Coyote,5,28
CT03,Bobcat,8,30

Because CSV files are simple text files, they can be opened by many different programs, including:

  • Excel,
  • Google Sheets,
  • R,
  • Python,
  • text editors,
  • and many other programs.

This makes CSV a very useful format for sharing and analyzing data.

From Excel to CSV

Many datasets begin their life in Excel.

That is completely fine.

However, when we begin analyzing the data in R, it is often useful to save a copy as a CSV file.

In Excel:

File → Save As

and select:

CSV (Comma delimited) (*.csv)

Save the file inside the data folder of your RStudio Project.

For example:

data/camera_data.csv
Keep your original data

Do not replace or modify your only copy of the original dataset.

A good workflow is to keep the original file unchanged and create a separate CSV file for analysis.

For example:

data/
├── camera_data_original.xlsx
└── camera_data.csv

Importing a CSV file

Base R includes the function:

read.csv()

which reads a CSV file and converts it into a data frame.

If our file is located here:

data/camera_data.csv

we can import it using:

camera_data <- read.csv("data/camera_data.csv")

There are two important things happening here.

First:

read.csv("data/camera_data.csv")

reads the file.

Second:

camera_data <-

stores the imported dataset in an R object called camera_data.

If we forget the assignment:

read.csv("data/camera_data.csv")
                 species n_events n_stations
1              Armadillo       33          6
2                   Bird       20          3
3          Black vulture       23          2
4                 Bobcat        3          2
5                 Coyote       37          2
6  Eastern gray squirrel        1          1
7           Fox squirrel        3          2
8               Gray fox        9          2
9                    Hog        9          4
10                 Human       18         12
11               Raccoon       35          5
12        Turkey vulture       53          4
13      Virginia opossum       23          3
14     White-tailed deer      104          7

R can still read and display the file, but we have not saved it as an object that we can continue working with.

Check that the data loaded correctly

Importing a file without an error does not necessarily mean that everything was read correctly.

We should always inspect the data after importing it.

For example:

head(camera_data)
                species n_events n_stations
1             Armadillo       33          6
2                  Bird       20          3
3         Black vulture       23          2
4                Bobcat        3          2
5                Coyote       37          2
6 Eastern gray squirrel        1          1
str(camera_data)
'data.frame':   14 obs. of  3 variables:
 $ species   : chr  "Armadillo" "Bird" "Black vulture" "Bobcat" ...
 $ n_events  : int  33 20 23 3 37 1 3 9 9 18 ...
 $ n_stations: int  6 3 2 2 2 1 2 2 4 12 ...
dim(camera_data)
[1] 14  3
names(camera_data)
[1] "species"    "n_events"   "n_stations"

These functions should already look familiar from the previous module.

We can also open the dataset using RStudio’s data viewer:

View(camera_data)
Always check your imported data

After importing a dataset, ask yourself:

  • Does it have the expected number of rows?
  • Does it have the expected number of columns?
  • Are the column names correct?
  • Are numeric columns actually numeric?
  • Did missing values import correctly?
  • Does the dataset look like the file I expected to load?

Never assume that a file was imported correctly just because R did not return an error.

Common CSV problems

Files do not always import exactly as expected.

A few common problems include:

Wrong file name

For example:

read.csv("data/camera-data.csv")

will not work if the actual file is called:

camera_data.csv

The names must match.

Wrong folder

This:

read.csv("camera_data.csv")

tells R to look for the file directly inside the project folder.

But if the file is inside:

data/

we need:

read.csv("data/camera_data.csv")

Capitalization

Depending on the operating system:

Camera_Data.csv

and:

camera_data.csv

may be treated as different file names.

Consistent file names help avoid these problems.

Does the file exist?

If R tells you that it cannot find a file, we can check whether R can see it.

For example:

file.exists("data/camera_data.csv")
[1] TRUE

If R returns:

TRUE

the file exists at that location.

If R returns:

FALSE

something about the path or file name is incorrect.

We can also see the files inside our data folder:

list.files("data")
[1] "camera_data.csv"  "camera_data.xlsx" "recordTable.csv" 

These two functions can be extremely useful when troubleshooting import problems.

Importing CSV files with readr

There are several ways to import the same type of file in R.

The tidyverse includes a package called readr that provides another function for reading CSV files:

read_csv()

Because we installed tidyverse at the beginning of the course, we can load it using:

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Then:

camera_data2 <- read_csv("data/camera_data.csv")

Notice the difference:

Base R       read.csv()

readr        read_csv()

Both functions can read CSV files.

For this course, you may see both, but later we will frequently use read_csv() because it works naturally with other tidyverse tools.

Note

You do not need to memorize multiple ways to import the same file.

What matters is understanding:

  1. where the file is,
  2. what type of file it is,
  3. which function can read it,
  4. and what object will store the result.

Importing Excel files

Sometimes we want to import an Excel file directly instead of converting it to CSV.

Base R does not include a function for reading .xlsx files, so we need an additional package.

We installed readxl during the Getting Started section.

Load it using:

library(readxl)

Then we can import an Excel file using:

camera_data3 <- read_excel( "data/camera_data.xlsx")

The function is called:

read_excel()

and comes from the readxl package.

Excel files with multiple sheets

An Excel workbook can contain several sheets.

We can see their names using:

excel_sheets("data/camera_data.xlsx")
[1] "camera_records" "secret_tab"    

If the workbook contains a sheet called:

camera_records

we can import that specific sheet using:

camera_data3 <- read_excel("data/camera_data.xlsx",
  sheet = "camera_records"
)

We can also select a sheet by position:

camera_data3 <- read_excel(
  "data/camera_data.xlsx",
  sheet = 1
)

CSV or Excel?

Both formats can be useful.

CSV

Advantages:

  • simple,
  • open format,
  • easy to share,
  • readable by almost any software,
  • good for analysis and reproducibility.

Limitations:

  • only stores one table,
  • does not preserve formatting,
  • does not store formulas or multiple sheets.

Excel

Advantages:

  • familiar to many users,
  • can contain multiple sheets,
  • useful for entering and reviewing data.

Limitations:

  • more complex file format,
  • formatting can sometimes hide data problems,
  • spreadsheet software may automatically modify dates or other values.

A common workflow is:

Enter/review data in Excel → save a clean CSV → analyze the CSV in R

But R can work directly with either format.

Importing data using RStudio

RStudio also provides a graphical interface for importing datasets.

In the Environment panel, select:

Import Dataset

RStudio will provide options for importing text and Excel files.

This can be useful when you are learning because RStudio shows a preview of the data and generates the corresponding R code.

However, once you understand the import function, it is better to keep the import command inside your script.

For example:

camera_data <- read_csv(
  "data/camera_data.csv"
)

This way, the analysis can be reproduced later without manually clicking through menus.

Tip

The graphical import tool is useful for learning.

But try to copy the generated code into your script so that you can reproduce the import later.

File names and column names

Good file organization begins before we import anything into R.

Try to use simple and consistent file names.

Instead of:

Camera Data FINAL version 2 updated!!!.xlsx

use something like:

camera_data.xlsx

or:

camera_data_2026.xlsx

The same principle applies to column names.

Instead of:

Camera Station
Number of detections
Habitat Type

consider:

station
detections
habitat

or:

camera_station
number_of_detections
habitat_type

Consistent names make working with data in R much easier.

Exporting data

Sometimes we want to save a dataset after modifying or summarizing it in R.

For CSV files, base R provides:

write.csv()

For example:

write.csv(
  camera_data,
  "outputs/camera_data_clean.csv",
  row.names = FALSE
)

This creates:

outputs/camera_data_clean.csv

We use:

row.names = FALSE

because otherwise base R will add an extra column containing the row numbers.

Exporting with readr

If we are using the tidyverse, we can also use:

write_csv(
  camera_data,
  "outputs/camera_data_clean.csv"
)

write_csv() does not add row names by default.

Again, you do not need to memorize every alternative.

The important idea is:

read  → bring data into R

write → save data from R

Keep raw data separate from outputs

Remember our project structure:

intro-r-course/
│
├── data/
├── scripts/
└── outputs/

A useful rule is:

data/

contains the original data that we received or collected.

outputs/

contains files created by our analysis.

For example:

intro-r-course/
│
├── data/
│   └── camera_data.csv
│
├── scripts/
│   └── module-04.R
│
└── outputs/
    └── camera_data_clean.csv
Important

Try not to overwrite your original data from R.

Keeping the raw data unchanged means that you can always return to the original information and reproduce every change using your script.

Practice at home

Tip

This activity should take approximately 15–20 minutes.

Open your intro-r-course project and create a new script called:

practice-04.R

Save it inside the scripts folder.

Use any small Excel dataset you have available, or create one with at least:

  • 5 rows,
  • 3 columns,
  • one column containing text,
  • one column containing numbers.

For example:

station habitat detections
CT01 Forest 8
CT02 Pasture 3
CT03 Forest 12
CT04 Pasture 0
CT05 Forest 5

Part 1: Prepare the data

  1. Save the Excel file inside your project’s data folder.
  2. Save a second copy as a .csv file.

Your folder should contain something like:

data/
├── practice_data.xlsx
└── practice_data.csv

Part 2: Import the CSV

Import the CSV file into an object called:

practice_data

Then use:

head()
str()
dim()
names()

to inspect the imported dataset.

Part 3: Import the Excel file

Load the readxl package and import the Excel version of the same dataset.

Save it as:

practice_excel

Compare:

class(practice_data)
class(practice_excel)

and inspect both objects.

Part 4: Export the data

Export practice_data into the outputs folder with the name:

practice_data_exported.csv

Finally, check that the new file appears inside the outputs folder.

# Practice for Module 4

# ---------------------------
# Import CSV
# ---------------------------

practice_data <- read.csv(
  "data/practice_data.csv"
)

# Inspect the data
head(practice_data)
str(practice_data)
dim(practice_data)
names(practice_data)


# ---------------------------
# Import Excel
# ---------------------------

library(readxl)

practice_excel <- read_excel(
  "data/practice_data.xlsx"
)

# Inspect the Excel data
head(practice_excel)
str(practice_excel)

# Compare classes
class(practice_data)
class(practice_excel)


# ---------------------------
# Export data
# ---------------------------

write.csv(
  practice_data,
  "outputs/practice_data_exported.csv",
  row.names = FALSE
)

The important thing is that you understand the complete workflow:

external file
      ↓
relative path
      ↓
read the file
      ↓
store it as an R object
      ↓
inspect the object
      ↓
work with the data
      ↓
write an output file