install.packages('rio') #install the package [only once]Exploring your data
Importing your dataset in R
The idea behind rio is to simplify the process of importing data into R and exporting data from R. This process is, probably unnecessarily, extremely complex for beginning R users. Indeed, R supplies an entire manual describing the process of data import/export. Faster, simpler, packages with fewer dependencies have been created for many of the file types described in that document. rio aims to unify data I/O (importing and exporting) into two simple functions: import() and export() so that beginners (and experienced R users) never have to think twice (or even once) about the best way to read and write R data.
The core advantage of rio is that it makes assumptions that the user is probably willing to make. Specifically, rio uses the file extension of a file name to determine what kind of file it is. This is the same logic used by Windows OS, for example, in determining what application is associated with a given file type. By taking away the need to manually match a file type (which a beginner may not recognize) to a particular import or export function, rio allows almost all common data formats to be read with the same function.
By making import and export easy, it’s an obvious next step to also use R as a simple data conversion utility. Transferring data files between various proprietary formats is always a pain and often expensive. The convert function therefore combines import and export to easily convert between file formats (thus providing a FOSS replacement for programs like Stat/Transfer or Sledgehammer.
Installing the rio package in R
library(rio) # load the library [every time you write a new script in which you want to import/export files]Setting the working directory
#set the working directory to the directory in which you data files are located
setwd('/path/to/the/folder/containing/this/document')Data Import
Rio allows you to import files in almost any format using one, typically single-argument, function. import() infers the file format from the file’s extension and calls the appropriate data import function for you, returning a simple data.frame. This works for any for the formats listed above.
mosq.dat <- import('data/GE-mosquito-ex.xlsx')
tick.dat <- import('data/GE-ticks-ex.xls')Viewing your data
#Use head() to examine the top rows of your dataset
head(mosq.dat) id municipality village destination latitude
1 36 Lagodekhi Lagodekhi nature reserve Tree, bush, grass 41.844352
2 36 Lagodekhi Lagodekhi nature reserve Tree, bush, grass 41.844352
3 37 Lagodekhi Lagodekhi nature reserve tree,grass,toilets 41.842328
4 37 Lagodekhi Lagodekhi nature reserve tree,grass,toilets 41.842328
5 38 Lagodekhi Lagodekhi nature reserve Tree, bush, grass 41.841335
6 38 Lagodekhi Lagodekhi nature reserve Tree, bush, grass 41.841335
longitude height temp humidity wind trap_set trap_collected point
1 46.2852763 580 28(32-23) 59 10 23.07.24/8:25 26.07.24/7:05 36a
2 46.2852763 580 28(32-23) 59 10 23.07.24/8:25 26.07.24/7:05 36b
3 46.284487 564 28(32-23) 59 10 23.07.24/8:55 26.07.24/7:25 37a
4 46.284487 564 28(32-23) 59 10 23.07.24/8:55 26.07.24/7:25 37b
5 46.284306 558 29(32-23) 57 10 23.07.24/9:15 26.07.24/7:40 38a
6 46.284306 558 29(32-23) 57 10 23.07.24/9:15 26.07.24/7:40 38b
Ae.albopictus.count Ae.albopictus.sex Cx.pipiens.count Cx.pipiens.sex
1 NA <NA> NA <NA>
2 NA <NA> NA <NA>
3 NA <NA> NA <NA>
4 NA <NA> NA <NA>
5 NA <NA> NA <NA>
6 NA <NA> NA <NA>
Other useful function for data exploration
#examine data structure
str(mosq.dat)'data.frame': 159 obs. of 17 variables:
$ id : num 36 36 37 37 38 38 39 39 40 40 ...
$ municipality : chr "Lagodekhi" "Lagodekhi" "Lagodekhi" "Lagodekhi" ...
$ village : chr "Lagodekhi nature reserve" "Lagodekhi nature reserve" "Lagodekhi nature reserve" "Lagodekhi nature reserve" ...
$ destination : chr "Tree, bush, grass" "Tree, bush, grass" "tree,grass,toilets" "tree,grass,toilets" ...
$ latitude : chr "41.844352" "41.844352" "41.842328" "41.842328" ...
$ longitude : chr "46.2852763" "46.2852763" "46.284487" "46.284487" ...
$ height : num 580 580 564 564 558 558 573 573 494 494 ...
$ temp : chr "28(32-23)" "28(32-23)" "28(32-23)" "28(32-23)" ...
$ humidity : num 59 59 59 59 57 57 59 59 51 51 ...
$ wind : num 10 10 10 10 10 10 10 10 10 10 ...
$ trap_set : chr "23.07.24/8:25" "23.07.24/8:25" "23.07.24/8:55" "23.07.24/8:55" ...
$ trap_collected : chr "26.07.24/7:05" "26.07.24/7:05" "26.07.24/7:25" "26.07.24/7:25" ...
$ point : chr "36a" "36b" "37a" "37b" ...
$ Ae.albopictus.count: num NA NA NA NA NA NA NA NA NA 2 ...
$ Ae.albopictus.sex : chr NA NA NA NA ...
$ Cx.pipiens.count : num NA NA NA NA NA NA NA NA NA NA ...
$ Cx.pipiens.sex : chr NA NA NA NA ...
#generate summary for each column of the dataset
summary(mosq.dat) id municipality village destination
Min. :36.00 Length:159 Length:159 Length:159
1st Qu.:47.00 Class :character Class :character Class :character
Median :58.00 Mode :character Mode :character Mode :character
Mean :61.72
3rd Qu.:77.25
Max. :99.00
NA's :59
latitude longitude height temp
Length:159 Length:159 Min. : 17.0 Length:159
Class :character Class :character 1st Qu.:224.8 Class :character
Mode :character Mode :character Median :287.0 Mode :character
Mean :314.1
3rd Qu.:439.8
Max. :580.0
NA's :71
humidity wind trap_set trap_collected
Min. :36.00 Min. : 0.000 Length:159 Length:159
1st Qu.:44.25 1st Qu.:10.000 Class :character Class :character
Median :49.00 Median :10.000 Mode :character Mode :character
Mean :53.50 Mean : 9.151
3rd Qu.:65.00 3rd Qu.:10.000
Max. :79.00 Max. :10.000
NA's :73 NA's :73
point Ae.albopictus.count Ae.albopictus.sex Cx.pipiens.count
Length:159 Min. : 1.00 Length:159 Min. : 1.000
Class :character 1st Qu.: 1.00 Class :character 1st Qu.: 1.000
Mode :character Median : 2.00 Mode :character Median : 3.000
Mean : 2.46 Mean : 5.892
3rd Qu.: 2.00 3rd Qu.: 7.000
Max. :10.00 Max. :22.000
NA's :109 NA's :94
Cx.pipiens.sex
Length:159
Class :character
Mode :character
#use View() to open the dataframe in a separate window
View(mosq.dat)Plotting you data
The $operator allow you to select specific columns from your data frame (mosq.dat). Let’s plot Ae. albopictus abundance using the plot() function:
plot(mosq.dat$Ae.albopictus.count)This is the simplest way to quickly visualize your data. For a more flexible approach to plotting we will need to load the “ggplot2” package.
# run this line of code in case this is the first time that you are using ggplot2
install.packages('ggplot2')# load the library
library(ggplot2)ggplot(data = mosq.dat, # specify your data frame
aes(x = c(x = c(1:length(Ae.albopictus.count))),
y = Ae.albopictus.count)) + geom_point() + xlab('') + ylab('Aedes albopictus trap data')Warning: Removed 109 rows containing missing values or values outside the scale range
(`geom_point()`).
There are five important steps that went into making that graph:
First, the
ggplot()call tells R that we want to create a ggplot objectSecond, the
data = mosq.dattells ggplot that everything we do should use the iris datasetThird, the
aes()specifies the aesthetics of the graph - what goes on the X and Y axes, but also any other data we want represented in our plotFourth, the
+lets us add additional steps to our plot. Note that the+must always be at the end of a line - putting it at the start of a line will mess up your session! If you see a+in the console instead of a>after trying to plot something, this is most likely what happened - press your escape key to exit the command.Finally, the
geomtells ggplot what sort of graph we want. A geom is just the type of plot (or, well, the geometric object which represents data) - sogeom_boxplot()generates a boxplot, whilegeom_col()makes a column chart.geom_pointgenerates a scatterplot, but there are plenty of other options to choose from!
For more information on ggplot functions and aesthetics see: Chapter 2.3.
# Remember: you can check the documentation for every function using the following options
?ggplot # or
help(ggplot)Working with times and dates in R
R has built-in classes to handle dates and times. The most common ones are:
Datefor dates.POSIXctandPOSIXltfor dates with times (timestamps).
The standard data-time format for R is YYYY-mm-dd hh:mm:ss. This is the reason why rio did not automatically recognize the “trap_set” and “trap_collected” as POSIXct but instead read them as simple character vectors (NB: When R is confused it defaults to “character”). In the code bellow we use the as.POSIXct() function to transform the character vectors into POSIXct.
mosq.dat$trap_set.posix <- as.POSIXct(mosq.dat$trap_set, format = '%y.%m.%d/%H:%M') # convert the trap-set time to POSIXct and add as new column
mosq.dat$trap_collected.posix <- as.POSIXct(mosq.dat$trap_collected, format = '%y.%m.%d/%H:%M') # convert the collection time to POSIXct and add as new columnCommon formatting symbols:
%Y- Year with century (2024)%y- Year without century (24)%m- Month (01-12)%d- Day of the month (01-31)%H- Hour (00-23)%M- Minute (00-59)
Leaflet: a glimpse into visualizing spatial data in R
install.packages('leaflet')library(leaflet)leaflet(mosq.dat) %>%
addTiles() %>%
addMarkers( ~longitude, ~latitude, # Longitude and Latitude columns
popup = ~village # Add popups with the name in the "village"column
)Examine error: if we look at the str(mosq.dat) command again, we will see that the longitude and latitude values are read as character but leaflet requires them to be numeric. We can quickly fix this with:
mosq.dat$longitude <- as.numeric(mosq.dat$longitude) # convert chr to num
mosq.dat$latitude <- as.numeric(mosq.dat$latitude) # convert chr to numleaflet(mosq.dat) %>%
addTiles() %>%
addMarkers( ~longitude, ~latitude, # Longitude and Latitude columns
popup = ~village # Add popups with the name in the "village"column
)Warning in validateCoords(lng, lat, funcName): Data contains 69 rows with
either missing or invalid lat/lon values and will be ignored