library(sf)
#Import Cambodia country border
= st_read("data_cambodia/cambodia.gpkg", layer = "country", quiet = TRUE)
country #Import provincial administrative border of Cambodia
= st_read("data_cambodia/cambodia.gpkg", layer = "education", quiet = TRUE)
education #Import district administrative border of Cambodia
= st_read("data_cambodia/cambodia.gpkg", layer = "district", quiet = TRUE)
district #Import roads data in Cambodia
= st_read("data_cambodia/cambodia.gpkg", layer = "road", quiet = TRUE)
road #Import health center data in Cambodia
= st_read("data_cambodia/cambodia.gpkg", layer = "hospital", quiet = TRUE) hospital
5 Mapping With R
5.1 Types of maps
The fonction mf_map()
is the central function of the package mapsf
(Giraud 2022a). It makes it possible to carry out most of the usual representations in cartography. These main arguments are:
x
, an sf object ;var
, the name of variable to present ;type
, the type of presentation.
5.1.1 Create a simple map
The following lines import the spatial information layers located in the geopackage cambodia.gpkg file.
library(mapsf)
mf_map(x = district, border = "white")
mf_map(x = country,lwd = 2, col = NA, add = TRUE)
mf_map(x = road, lwd = .5, col = "ivory4", add = TRUE)
mf_map(x = hospital, pch = 20, cex = 1, col = "#FE9A2E", add = TRUE)
5.1.2 Proportional symbol map
Proportional symbol maps are used to represent inventory variables (absolute quantitative variables, sum and average make sense). The function mf_map(..., type = "prop")
proposes this representation.
#District
mf_map(x = district)
# Proportional symbol
mf_map(
x = district,
var = "T_POP",
val_max = 700000,
type = "prop",
col = "#148F77",
leg_title = "Population 2019"
)
# Title
mf_title("Distribution of population in provincial level")
5.1.2.1 Compare multiple map
It is possible to fix the dimensions of the largest symbol corresponding to a certain value with the arguments inches
and val_max
. We can use construct maps with comparable proportional symbols.
par(mfrow = c(1,2)) #Displaying two maps facing each other
#district
mf_map(x = district, border = "grey90", lwd = .5)
# Add male Population
mf_map(
x = district,
var = "Male",
type = "prop",
col = "#1F618D",
inches = 0.2,
val_max = 300000,
leg_title = "Male",
leg_val_cex = 0.5,
)mf_title("Male Population by Distict") #Adding map title
#district
mf_map(x = district, border = "grey90", lwd = .5)
# Add female Population
mf_map(
x = district,
var = "Female",
type = "prop",
col = "#E74C3C",
inches = 0.2,
val_max = 300000,
leg_title ="Female",
leg_val_cex = 0.5
)mf_title("Female Population by Distict") #Adding map title
Here we have displayed two maps facing each other, see the point Displaying several maps on the same figure for more details.
5.1.3 Choropleth map
Choropleth maps are used to represent ratio variables (relative quantitative variables, mean has meaning, sum has no meaning).
For this type of representation, you must first:
- choose a discretization method to transform a continuous statistical series into classes defined by intervals,
- choose a number of classes,
- choose a color palette.
The function mf_map(…, type = “choro”)makes it possible to create choroplete maps. The arguments nbreaks and breaks are used to parameterize the discretizations, and the function mf_get_breaks()
makes it possible to work on the discretizations outside the function mf_map()
. Similarly, the argument palis used to fill in a color palette, but several functions can be used to set the palettes apart from the (mf_get_pal
…) function.
# Population density (inhabitants/km2) using the sf::st_area() function
$DENS <- 1e6 * district$T_POP / as.numeric(st_area(district)) #Calculate population density
districtmf_map(
x = district,
var = "DENS",
type = "choro",
breaks = "quantile",
pal = "BuGn",
lwd = 1,
leg_title = "Distribution of population\n(inhabitants per km2)",
leg_val_rnd = 0
)mf_title("Distribution of the population in (2019)")
= st_read("data_cambodia/cambodia.gpkg", layer = "cases", quiet = TRUE) # load cases layer
cases = subset(cases, Disease == "W fever") # subset data to only keep W fever cases
cases <- read.csv("data_cambodia/khm_admpop_adm2_2016_v2.csv") # read population data
population <- population[, c("ADM2_PCODE", "T_TL")] # just select few columns
population $T_TL <- as.numeric(gsub(",","",population$T_TL)) # Remove commas (not supposed to be in the dataframe)
population$cases <- lengths(st_intersects(district, cases)) # count points in polygons
district<- merge(district,
district
population,by = "ADM2_PCODE") # merge shape with population data
$incidence <- district$cases / district$T_TL * 100000 # calculate incidence
district
mf_map(x = district,
var = "incidence",
type = "choro",
leg_title = "Incidence (per 100 000)")
mf_layout(title = "Incidence of W Fever in Cambodia")
5.1.3.1 Discretisation
The fonction mf_get_breaks()
provides the methods of discretization of classic variables: quantiles, average/standard deviation, equal amplitudes, nested averages, Fisher-Jenks, geometric, etc.
$enrol_g_pct = 100 * education$enrol_girl/education$t_enrol #Calculate percentage of enrolled girl student
education
= mf_get_breaks(education$enrol_g_pct, nbreaks = 6, breaks = "equal", freq = TRUE)
d1 = mf_get_breaks(education$enrol_g_pct, nbreaks = 6, breaks = "quantile")
d2 = mf_get_breaks(education$enrol_g_pct, nbreaks = 6, breaks = "geom")
d3 = mf_get_breaks(education$enrol_g_pct, breaks = "msd", central = FALSE) d4
5.1.3.2 Color palettes
The argument pal
de mf_map()
is dedicated to choosing a color palette. The palettes provided by the function hcl.colors()
can be used directly.
mf_map(x = education, var = "enrol_g_pct", type = "choro",
breaks = d3, pal = "Reds 3")
The fonction mf_get_pal()
allows you to build a color palette. This function is especially useful for creating balanced asymmetrical diverging palettes.
<- mf_get_pal(n = c(4,6), palette = c("Burg", "Teal"))
mypal image(1:10, 1, as.matrix(1:10), col=mypal, xlab = "", ylab = "", xaxt = "n",
yaxt = "n",bty = "n")
5.1.3.3 For a point layer
It is possible to use this mode of presentation in specific implementation also.
<- st_centroid(district)
dist_c mf_map(district)
mf_map(
x = dist_c,
var = "DENS",
type = "choro",
breaks = "quantile",
nbreaks = 5,
pal = "PuRd",
pch = 23,
cex = 1.5,
border = "white",
lwd = .7,
leg_pos = "topleft",
leg_title = "Distribution of population\n(inhabitants per km2)",
leg_val_rnd = 0,
add = TRUE
)mf_title("Distribution of population in (2019)")
5.1.4 Typology map
Typology maps are used to represent qualitative variables. The function mf_map(..., type = "typo")
proposes this representation.
mf_map(
x = district,
var="Status",
type = "typo",
pal = c('#E8F9FD','#FF7396','#E4BAD4','#FFE3FE'),
lwd = .7,
leg_title = ""
)mf_title("Administrative status by size of area")
5.1.4.1 Ordering value in the legend
The argument val_order
is used to order the categories in the
mf_map(
x = district,
var="Status",
type = "typo",
pal = c('#E8F9FD','#FF7396','#E4BAD4','#FFE3FE'),
val_order = c("1st largest district", "2nd largest district", "3rd largest district","<4500km2"),
lwd = .7,
leg_title = ""
)mf_title("Administrative status by size of area")
5.1.4.2 Map of point
When the implantation of the layer is punctual, symbols are used to carry the colors of the typology.
#extract centroid point of the district
<- st_centroid(district[district$Status != "<4500km2", ])
dist_ctr mf_map(district)
mf_map(
x = dist_ctr,
var = "Status",
type = "typo",
cex = 2,
pch = 22,
pal = c('#FF7396','#E4BAD4','#FFE3FE'),
leg_title = "",
leg_pos = "bottomright",
add = TRUE
)mf_title("Administrative status by size of area")
5.1.4.3 Map of lines
#Selection of roads that intersect the city of Siem Reap
<- district[district$ADM1_EN == "Phnom Penh", ]
pp <- road[st_intersects(x = road, y = pp, sparse = FALSE), ]
road_pp mf_map(pp)
mf_map(
x = road_pp,
var = "fclass",
type = "typo",
lwd = 1.2,
pal = mf_get_pal(n = 6, "Tropic"),
leg_title = "Types of road",
leg_pos = "topright",
leg_frame = T,
add = TRUE
)mf_title("Administrative status")
5.1.5 Map of stocks and ratios
The function mf_map(..., var = c("var1", "var2"), type = "prop_choro")
represents proportional symbols whose areas are proportional to the values of one variable and whose color is based on the discretization of a second variable. The function uses the arguments of the functions mf_map(..., type = "prop")
and mf_map(..., type = "choro")
.
mf_map(x = district)
mf_map(
x = district,
var = c("T_POP", "DENS"),
val_max = 500000,
type = "prop_choro",
border = "grey60",
lwd = 0.5,
leg_pos = c("bottomright", "bottomleft"),
leg_title = c("Population", "Density of\n population\n(inhabitants per km2)"),
breaks = "q6",
pal = "Blues 3",
leg_val_rnd = c(0,1))
mf_title("Population")
5.1.6 Map of stocks and categories
The function mf_map(..., var = c("var1", "var2"), type = "prop_typo")
represents proportional symbols whose areas are proportional to the values of one variable and whose color is based on the discretization of a second variable. The function uses the arguments of the mf_map(..., type = "prop")
and function mf_map(..., type = "typo")
.
mf_map(x = district)
mf_map(
x = district,
var = c("Area.Km2.", "Status"),
type = "prop_typo",
pal = c('#E8F9FD','#FF7396','#E4BAD4','#FFE3FE'),
val_order = c("<4500km2","1st largest district", "2nd largest district", "3rd largest district"),
leg_pos = c("bottomleft","topleft"),
leg_title = c("Population\n(2019)",
"Statut administratif"),
)mf_title("Population")
5.2 Layout
To be finalized, a thematic map must contain certain additional elements such as: title, author, source, scale, orientation…
5.2.1 Example data
The following lines import the spatial information layers located in the geopackage cambodia.gpkg file.
library(sf)
= st_read("data_cambodia/cambodia.gpkg", layer = "country", quiet = TRUE) #Import Cambodia country border
country = st_read("data_cambodia/cambodia.gpkg", layer = "education", quiet = TRUE) #Import provincial administrative border of Cambodia
education = st_read("data_cambodia/cambodia.gpkg", layer = "district", quiet = TRUE) #Import district administrative border of Cambodia
district = st_read("data_cambodia/cambodia.gpkg", layer = "road", quiet = TRUE) #Import roads data in Cambodia
road = st_read("data_cambodia/cambodia.gpkg", layer = "hospital", quiet = TRUE) #Import hospital data in Cambodia
hospital = st_read("data_cambodia/cambodia.gpkg", layer = "cases", quiet = TRUE) #Import example data of fever_cases in Cambodia cases
5.2.2 Themes
The function mf_theme()
defines a cartographic theme. Using a theme allows you to define several graphic parameters which are then applied to the maps created with mapsf
. These parameters are: the map margins, the main color, the background color, the position and the aspect of the title. A theme can also be defined with the mf_init()
and function mf_export()
.
5.2.2.1 Use a predefined theme
A series of predefined themes are available by default (see ?mf_theme
).
library(mapsf)
# use of a background color for the figure, to see the use of margin
<- par(mfrow = c(2,2))
opar # Using a predefined theme
mf_theme("default")
mf_map(district)
mf_title("Theme : 'default'")
mf_theme("darkula")
mf_map(district)
mf_title("Theme : 'darkula'")
mf_theme("candy")
mf_map(district)
mf_title("Theme : 'candy'")
mf_theme("nevermind")
mf_map(district)
mf_title("Theme : 'nevermind'")
par(opar)
5.2.2.2 Modify an existing theme
It is possible to modify an existing theme. In this example, we are using the “default” theme and modifying a few settings.
library(mapsf)
<- par(mfrow = c(1,2))
opar mf_theme("default")
mf_map(district)
mf_title("default")
mf_theme("default", tab = FALSE, font = 4, bg = "grey60", pos = "center")
mf_map(district)
mf_title("modified default")
par(opar)
5.2.2.3 Create a theme
It is also possible to create a theme.
mf_theme(
bg = "lightblue", # background color
fg = "tomato1", # main color
mar = c(1,0,1.5,0), # margin
tab = FALSE, # "tab" style for the title
inner = FALSE, # title inside or outside of map area
line = 1.5, # space dedicated to title
pos = "center", # heading position
cex = 1.5, # title size
font = 2 # font types for title
)mf_map(district)
mf_title("New theme")
5.2.3 Titles
The function mf_title()
adds a title to a map.
mf_theme("default")
mf_map(district)
mf_title("Map title")
It is possible to customize the appearance of the title
mf_map(district)
mf_title(
txt = "Map title",
pos = "center",
tab = FALSE,
bg = "tomato3",
fg = "lightblue",
cex = 1.5,
line = 1.7,
font = 1,
inner = FALSE
)
5.2.4 Arrow orientation
The function mf_arrow()
allows you to choose the position and aspect of orientation arrow.
mf_map(district)
mf_arrow()
5.2.5 Scale
The function mf_scale()
allows you to choose the position and the aspect of the scale.
mf_map(district)
mf_scale(
size = 60,
lwd = 1,
cex = 0.7
)
5.2.6 Credits
The function mf_credits()
displays a line of credits (sources, author, etc.).
mf_map(district)
mf_credits("IRD\nInstitut Pasteur du Cambodge, 2022")
5.2.7 Complete dressing
The function mf_layout()
displays all these elements.
mf_map(district)
mf_layout(
title = "Cambodia",
credits = "IRD\nInstitut Pasteur du Cambodge, 2022",
arrow = TRUE
)
5.2.8 Annotations
mf_map(district)
mf_annotation(district[district$ADM2_EN == "Bakan",], txt = "Bakan", col_txt = "darkred", halo = TRUE, cex = 1.5)
5.2.9 Legends
mf_map(district)
mf_legend(
type = "prop",
val = c(1000,500,200,10),
inches = .2,
title = "Population",
pos = "topleft"
)mf_legend(
type = "choro",
val = c(0,10,20,30,40),
pal = "Greens",
pos = "bottomright",
val_rnd = 0
)
5.2.10 Labels
The function mf_label()
is dedicated to displaying labels.
<- district[st_intersects(district, district[district$ADM2_EN == "Bakan", ], sparse = F), ]
dist_selected
mf_map(dist_selected)
mf_label(
x = dist_selected,
var = "ADM2_EN",
col= "darkgreen",
halo = TRUE,
overlap = FALSE,
lines = FALSE
)mf_scale()
The argument halo = TRUE
allows to display a slight halo around the labels and the argument overlap = FALSE
allows to create non-overlapping labels.
5.2.11 Center the map on a region
The function mf_init()
allows you to initialize a map by centering it on a spatial object.
mf_init(x = dist_selected)
mf_map(district, add = TRUE)
mf_map(dist_selected, col = NA, border = "#29a3a3", lwd = 2, add = TRUE)
5.2.12 Displaying several maps on the same figure
Here you have to use mfrow
of the function par()
. The first digit represents the number of of rows and second the number of columns.
# define the figure layout (1 row, 2 columns)
par(mfrow = c(1, 2))
# first map
mf_map(district)
mf_map(district, "Male", "prop", val_max = 300000)
mf_title("Population, male")
# second map
mf_map(district)
mf_map(district, "Female", "prop", val_max = 300000)
mf_title("Population, female")
5.2.13 Exporting maps
It is quite difficult to export figures (maps or others) whose height/width ratio is satisfactory. The default ratio of figures in png format is 1 (480x480 pixels):
<- district[district$ADM2_PCODE == "KH0808", ]
dist_filter png("img/dist_filter_1.png")
mf_map(dist_filter)
mf_title("Filtered district")
dev.off()
On this map a lot of space is lost to the left and right of the district.
The function mf_export()
allows exports of maps whose height/width ratio is controlled and corresponds to that of a spatial object.
mf_export(dist_filter, "img/dist_filter_2.png", width = 480)
mf_map(dist_filter)
mf_title("Filtered district")
dev.off()
The extent of this map is exactly that of the displayed region.
5.2.14 Adding an image to a map
This can be useful for adding a logo, a pictograph. The function readPNG()
of package png
allows the additional images on the figure.
mf_theme("default", mar = c(0,0,0,0))
library(png)
<- readPNG("img/ird_logo.png") #Import image
logo <- dim(logo)[2:1]*200 #Image dimension in map unit (width and height of the original image)
pp
#The upper left corner of the department's bounding box
<- st_bbox(district)[c(1,4)]
xy mf_map(district, col = "#D1914D", border = "white")
rasterImage(
image = logo,
xleft = xy[1] ,
ybottom = xy[2] - pp[2],
xright = xy[1] + pp[1],
ytop = xy[2]
)
5.2.15 Place an item precisely on the map
The function locator()
allows clicking on the figure and obtaining the coordinate of a point in the coordinate system of the figure (of the map).
# locator(1) # click to get coordinate on map
# points(locator(1)) # click to plot point on map
# text(locator(1), # click to place the item on map
# labels ="Located any texts on map",
# adj = c(0,0))
locator()
peut être utilisée sur la plupart des graphiques (pas ceux produits avec ggplot2
).
5.2.16 Add shading to a layer
The function mf_shadow()
allows to create a shadow to a layer of polygons.
mf_shadow(district)
mf_map(district, add=TRUE)
5.2.17 Creating Boxes
The function mf_inset_on()
allows to start creation a box. You must then “close” the box with mf_inset_off()
.
mf_init(x = dist_selected, theme = "agolalight", expandBB = c(0,.1,0,.5))
mf_map(district, add = TRUE)
mf_map(dist_selected, col = "tomato4", border = "tomato1", lwd = 2, add = TRUE)
# Cambodia inset box
mf_inset_on(x = country, pos = "topright", cex = .3)
mf_map(country, lwd = .5, border= "grey90")
mf_map(dist_selected, col = "tomato4", border = "tomato1", lwd = .5, add = TRUE)
mf_scale(size = 100, pos = "bottomleft", cex = .6, lwd = .5)
mf_inset_off()
# District inset box
mf_inset_on(x = district, pos = "bottomright", cex = .3)
mf_map(district, lwd = 0.5, border= "grey90")
mf_map(dist_selected, col = "tomato4", border = "tomato1", lwd = .5, add = TRUE)
mf_scale(size = 100, pos = "bottomright", cex = .6, lwd = .5)
mf_inset_off()
# World inset box
mf_inset_on(x = "worldmap", pos = "topleft")
mf_worldmap(dist_selected, land_col = "#cccccc", border_col = NA,
water_col = "#e3e3e3", col = "tomato4")
mf_inset_off()
mf_title("Bakan district and its surroundings")
mf_scale(10, pos = 'bottomleft')
5.3 3D maps
5.3.1 linemap
The package linemap
(Giraud 2021) allows you to make maps made up of lines.
library(linemap)
library(mapsf)
library(sf)
library(dplyr)
= st_read("data_cambodia/PP.gpkg", quiet = TRUE) # import Phnom Penh administrative border
pp <- getgrid(x = pp, cellsize =1000, var = "DENs") # create population density in grid format (pop density/1km)
pp_pop_dens
mf_init(pp)
linemap(
x = pp_pop_dens,
var = "DENs",
k = 1,
threshold = 5,
lwd = 1,
col = "ivory1",
border = "ivory4",
add = T)
mf_title("Phnom Penh Population Density, 2019")
mf_credits("Humanitarian Data Exchange, 2022\nunit data:km2")
# url = "https://data.humdata.org/dataset/1803994d-6218-4b98-ac3a-30c7f85c6dbc/resource/f30b0f4b-1c40-45f3-986d-2820375ea8dd/download/health_facility.zip"
# health_facility.zip = "health_facility.zip"
# download.file(url, destfile = health_facility.zip)
# unzip(health_facility.zip) # Unzipped files are in a new folder named Health
# list.files(path="Health")
5.3.2 Relief Tanaka
We use the tanaka
package (Giraud 2022b) which provides a method (Tanaka 1950) used to improve the perception of relief.
library(tanaka)
library(terra)
<- rast("data_cambodia/khm_pd_2019_1km_utm.tif") # Import population raster data (in UTM)
rpop = st_read("data_cambodia/cambodia.gpkg", layer = "district", quiet = TRUE) # Import Cambodian districts layer
district <- st_transform(district, st_crs(rpop)) # Transform data into the same coordinate system
district
<- focalMat(x = rpop, d = c(1500), type = "Gauss") # Raster smoothing
mat <- focal(x = rpop, w = mat, fun = sum, na.rm = TRUE)
rpopl
# Mapping
<- hcl.colors(8, "Reds", alpha = 1, rev = T)[-1]
cols mf_theme("agolalight")
mf_init(district)
tanaka(x = rpop, breaks = c(0,10,25,50,100,250,500,64265),
col = cols, add = T, mask = district, legend.pos = "n")
mf_legend(type = "choro", pos = "bottomright",
val = c(0,10,25,50,100,250,500,64265), pal = cols,
bg = "#EDF4F5", fg = NA, frame = T, val_rnd = 0,
title = "Population\nper km2")
mf_title("Population density of Cambodia, 2019")
mf_credits("Humanitarian Data Exchange, 2022",
bg = "#EDF4F5")
5.4 Cartographic Transformation
classical anamorphosis is a representation of States(or any cells) by rectangle or any polygons according to a quantities attached to them. (…) We strive to keep the general arrangement of meshes or the silhouette of the continent.”
Brunet, Ferras, and Théry (1993)
3 types of anamorphoses or cartograms are presented here:
- Dorling’s cartograms (Dorling 1996)
- Non-contiguous cartograms (Olson 1976)
- Contiguous cartograms (Dougenik, Chrisman, and Niemeyer 1985)
To make the cartograms we use the package cartogram
(Jeworutzki 2020).
5.4.1 Dorling’s cartograms
The territories are represented by figures (circles, squares or rectangles) which do not overlap, the surface of which are proportional to a variable. The proportion of the figures are defined according to the starting positions.
You can name the circles to get your bearings and/or use the color to make clusters appear and better identify the geographical blocks.
library(mapsf)
library(cartogram)
<- st_read("data_cambodia/cambodia.gpkg", layer = "district" , quiet = TRUE)
district <- cartogram_dorling(x = district, weight = "T_POP", k = 0.7)
dist_dorling mf_map(dist_dorling, col = "#40E0D0", border= "white")
mf_label(
x = dist_dorling[order(dist_dorling$T_POP, decreasing = TRUE), ][1:10,],
var = "ADM2_EN",
overlap = FALSE,
# show.lines = FALSE,
halo = TRUE,
r = 0.15
)mf_title("Population of District - Dorling Cartogram")
The parameter k
allows to vary the expansion factor of the circles.
5.4.2 Non-continuous cartograms
The size of the polygons is proportional to a variable. The arrangement of the polygons relative to each other is preserved. The shape of the polygons is similar.
(Cauvin, Escobar, and Serradj 2013)
<- cartogram_ncont(x = district, weight = "T_POP", k = 1.2)
dist_ncont mf_map(district, col = NA, border = "#FDFEFE", lwd = 1.5)
mf_map(dist_ncont, col = "#20B2AA", border= "white", add = TRUE)
mf_title("Population of District - Non-continuous cartograms")
The parameter k
allows to vary the expansion of the polygons.
5.4.3 Continuous cartograms
The size of the polygons is proportional to variable. The arrangement of the polygons relative to each other is preserved. To maintain contiguity, the sape of the polygons is heavily transformed.
It is a “real geographical map”: topology and contiguity are preserved.
<- cartogram_cont(x = district, weight = "DENs", maxSizeError = 6) dist_ncont
Mean size error for iteration 1: 15.8686749410166
Mean size error for iteration 2: 12.1107731631101
Mean size error for iteration 3: 9.98940057337996
Mean size error for iteration 4: 8.62323208787643
Mean size error for iteration 5: 7.60706404894655
Mean size error for iteration 6: 6.83561617758241
Mean size error for iteration 7: 10.1399490743501
Mean size error for iteration 8: 5.79418495291592
mf_map(dist_ncont, col = "#66CDAA", border= "white", add = FALSE)
mf_title("Population of District - Continuous cartograms")
mf_inset_on(district, cex = .2, pos = "bottomleft")
mf_map(district, lwd = .5)
mf_inset_off()
5.4.4 Stengths and weaknessses of cartograms
cartograms are cartographic representations perceived as innovative (although the method is 40 years old). These very generalize images capture quantities and gradients well. These are real communication images that provoke, arouse interest, convey a strong message, challenge.
But cartograms induce a loss of visual cues (difficult to find one’s country or region on the map), require a reading effort which can be significant and do not make it possible to manage missing data.