31 Handle NAs gracefully
Objective
Handle NA values in input vectors.
We’ve been using xi.inner()
to access the f64
value of an Rfloat
. This is an infallible method. It always provides the inner value of the Rfloat
. However, we may want to handle NA values differently.
To handle NA
values explicitly (rather than hoping our encode()
function returns an error), we can check for the pressence of NA
in both xi
and yi
. We can then match
on the boolean value and choose what to do!
match
isn’t only for enums! When we match
on booleans, there are only two variants: true
or false
. We can also perform nested match statements!
Example
Here we perform a nested match statement on the Result
from parsing a string slice to an integer.
let num_parsed = "10".parse::<i32>();
match num_parsed {
Ok(num) => {
match num > 10 {
true => println!("Parsed number is greater than 10!"),
false => println!("Parsed number is less than or equal to 10")
}
},
Err(e) => println!("Failed to parse number with error: {e:?}")
}
Exercise
- Check if either
xi
oryi
is an NA (usexi.is_na()
) and store in a variableis_missing
- Match on
is_missing
:- if
true
return an NA - otherwise attempt to use
encode()
and match on theResult
- if
View solution
#[extendr]
fn gh_encode(x: Doubles, y: Doubles, length: usize) -> Strings {
if length == 0 || length > 12 {
"`length` must be between 1 and 12");
throw_r_error(}
.into_iter()
x.zip(y.into_iter())
.map(|(xi, yi)| {
let is_missing = xi.is_na() || yi.is_na();
match is_missing {
true => Rstr::na(),
false => {
let coord = Coord {
: xi.inner(),
x: yi.inner(),
y};
match encode(coord, length) {
Ok(res) => Rstr::from(res),
Err(_) => Rstr::na(),
}
}
}
})
.collect::<Strings>()
}