pub struct AsCharacterVec(pub Vec<Option<String>>);Expand description
A character vector read like R’s as.character(): from an atomic vector of
any type, a factor by its labels. NA of any type is None.
Identifiers in R data often arrive as numbers or factors: subject IDs,
visit numbers, or grouping columns read by read.csv(). A Vec<String>
parameter accepts character input only, so a function that treats such
values as labels would need an R wrapper calling as.character() first.
This marker does that conversion itself, and the strings are exactly the
ones R produces elsewhere, because R makes them.
§Reading rules
| R input | Result |
|---|---|
| character | as is; NA_character_ → None. "NA" and "" stay values |
| integer, double | R’s own formatting (doubles to 15 significant digits): 0.1 + 0.2 → "0.3", 1e6 → "1e+06", 100 → "100", NaN → "NaN", Inf → "Inf"; NA → None |
| logical | "TRUE" / "FALSE"; NA → None |
| complex | "1+2i"; NA → None |
| raw | two hex digits: as.raw(255) → "ff" |
classed object (factor, Date, POSIXct, …) | its as.character() method: factor labels (never the codes), "2024-01-15" for a Date, "2024-01-15 10:30:00" for a POSIXct |
list, data frame, NULL, … | SexpError::Type |
A plain atomic vector is converted with R’s coerceVector() (what the
as.character() primitive does for it); the text never comes from Rust
formatting, which would give "0.30000000000000004" for 0.1 + 0.2. A
vector with a class attribute (is.object(x)) is passed to
as.character(x), evaluated as if at top level: base R’s as.character
(a user binding of that name does not interfere), with S3 and S4 methods
registered by packages or defined in the global environment. A Date is a
double underneath, and coerceVector() alone would give its day count
("19737"). An error in the method becomes the conversion error, as does a
method that returns something other than a character vector.
Names and dim are dropped, as as.character() drops them: a matrix is
read in column-major order. Zero-length input gives an empty vector.
Unlike AsNumericVec, which reads the
token "NA" and blank strings as missing, only NA itself is None
here: as.character() keeps "NA" and "" as strings. NaN becomes
"NaN" (no_na refuses it in R, as anyNA() counts it). no_na also
checks the converted value after the call, so it refuses an NA only the
conversion produces: a factor NA level (factor(x, exclude = NULL),
whose code is not NA) or a class’s as.character() method returning
NA. A type alias or a #[derive(TryFromSexp)] newtype of the marker is
checked the same way.
Option<AsCharacterVec> (and Option<AsCharacter>) also accept NULL as
None.
§IntoR
The markers convert to R as their inner Vec<Option<String>> /
Option<String>: a character vector with NA_character_ for None,
which the marker reads back unchanged ("NA" and "" stay strings), and
Option<marker> gives NULL for None. That is what lets a
#[miniextendr] trait method take a marker parameter: the trait’s View
converts each argument with IntoR and the implementing side reads it
back with TryFromSexp. A #[miniextendr] function returning a marker
gives the same R value as returning .0; returning .0 stays the idiom.
§Example
use miniextendr_api::{miniextendr, AsCharacterVec};
use std::collections::HashSet;
#[miniextendr]
fn n_subjects(ids: AsCharacterVec) -> i32 {
let distinct: HashSet<String> = ids.0.into_iter().flatten().collect();
i32::try_from(distinct.len()).expect("fewer than 2^31 subjects")
}
// R: n_subjects(c(101L, 102L, 101L)) → 2
// n_subjects(factor(c("S1", "S2", NA))) → 2 (labels, not codes)
// n_subjects(c(0.1 + 0.2, 0.3)) → 1 (both read as "0.3")
// n_subjects(list(1)) → error: 'ids' must be atomicTuple Fields§
§0: Vec<Option<String>>Trait Implementations§
Source§impl Clone for AsCharacterVec
impl Clone for AsCharacterVec
Source§impl Debug for AsCharacterVec
impl Debug for AsCharacterVec
Source§impl Default for AsCharacterVec
impl Default for AsCharacterVec
Source§impl Eq for AsCharacterVec
impl Eq for AsCharacterVec
Source§#[doc(hidden)]fn assert_fields_are_eq(&self)
#[doc(hidden)]fn assert_fields_are_eq(&self)
derive_eq_internals)1.0.0 (const: unstable) · Source§#[doc(hidden)]fn assert_receiver_is_total_eq(&self)
#[doc(hidden)]fn assert_receiver_is_total_eq(&self)
implementation detail of #[derive(Eq)]
Source§impl IntoR for AsCharacterVec
impl IntoR for AsCharacterVec
Source§type Error = <Vec<Option<String>> as IntoR>::Error
type Error = <Vec<Option<String>> as IntoR>::Error
Source§fn try_into_sexp(self) -> Result<SEXP, Self::Error>
fn try_into_sexp(self) -> Result<SEXP, Self::Error>
Source§unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error>
unsafe fn try_into_sexp_unchecked(self) -> Result<SEXP, Self::Error>
Source§unsafe fn into_sexp_unchecked(self) -> SEXP
unsafe fn into_sexp_unchecked(self) -> SEXP
Source§impl PartialEq for AsCharacterVec
impl PartialEq for AsCharacterVec
impl StructuralPartialEq for AsCharacterVec
Source§impl TryFromSexp for AsCharacterVec
impl TryFromSexp for AsCharacterVec
Source§fn __mx_has_na(&self) -> bool
fn __mx_has_na(&self) -> bool
#[miniextendr(no_na)]
refuses after the conversion. Read moreSource§fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error>
fn try_from_sexp(sexp: SEXP) -> Result<Self, Self::Error>
Source§const NATIVE_BORROW: Option<NativeBorrow> = None
const NATIVE_BORROW: Option<NativeBorrow> = None
Source§const CHARACTER_ONLY: bool = false
const CHARACTER_ONLY: bool = false
NULL, is a character vector or a factor. Read moreSource§#[doc(hidden)]const __MX_EXPECTATION: Option<&'static str> = None
#[doc(hidden)]const __MX_EXPECTATION: Option<&'static str> = None
#[miniextendr] cannot tell from the type as written: the
<expected> of a failed conversion’s '<p>' must be <expected>: .... Read moreSource§unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error>
unsafe fn try_from_sexp_unchecked(sexp: SEXP) -> Result<Self, Self::Error>
Source§#[doc(hidden)]unsafe fn __mx_try_from_rooted(root: Root<'_>) -> Result<Self, Self::Error>
#[doc(hidden)]unsafe fn __mx_try_from_rooted(root: Root<'_>) -> Result<Self, Self::Error>
Source§#[doc(hidden)]fn __mx_input_has_na(&self, input: SEXP) -> bool
#[doc(hidden)]fn __mx_input_has_na(&self, input: SEXP) -> bool
#[miniextendr(no_na)] refuses this converted argument, read
from input (the R value it converted from), when no R guard ran. Read moreSource§#[doc(hidden)]fn __mx_try_from_sexp_with_check(
sexp: SEXP,
check: &ElementCheck<'_>,
) -> Result<Self, SexpError>
#[doc(hidden)]fn __mx_try_from_sexp_with_check(
sexp: SEXP,
check: &ElementCheck<'_>,
) -> Result<Self, SexpError>
check, an element type’s
TryFromSexpElement::check_sexp,
on the R value that carries an element’s class (#1837). Read moreSource§#[doc(hidden)]unsafe fn __mx_try_from_sexp_unchecked_with_check(
sexp: SEXP,
check: &ElementCheck<'_>,
) -> Result<Self, SexpError>
#[doc(hidden)]unsafe fn __mx_try_from_sexp_unchecked_with_check(
sexp: SEXP,
check: &ElementCheck<'_>,
) -> Result<Self, SexpError>
Auto Trait Implementations§
impl Freeze for AsCharacterVec
impl RefUnwindSafe for AsCharacterVec
impl Send for AsCharacterVec
impl Sync for AsCharacterVec
impl Unpin for AsCharacterVec
impl UnsafeUnpin for AsCharacterVec
impl UnwindSafe for AsCharacterVec
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ConsumingFallible for Twhere
T: Clone,
Source§impl<I> OptionInner for I
impl<I> OptionInner for I
Source§const OPTION_NATIVE_BORROW: Option<NativeBorrow> = const OPTION_NATIVE_BORROW: Option<NativeBorrow> =
<Option<I> as TryFromSexp>::NATIVE_BORROW;
const OPTION_NATIVE_BORROW: Option<NativeBorrow> = const OPTION_NATIVE_BORROW: Option<NativeBorrow> = <Option<I> as TryFromSexp>::NATIVE_BORROW;
<Option<Self> as TryFromSexp>::NATIVE_BORROW.Source§const OPTION_CHARACTER_ONLY: bool = const OPTION_CHARACTER_ONLY: bool =
<Option<I> as TryFromSexp>::CHARACTER_ONLY;
const OPTION_CHARACTER_ONLY: bool = const OPTION_CHARACTER_ONLY: bool = <Option<I> as TryFromSexp>::CHARACTER_ONLY;
<Option<Self> as TryFromSexp>::CHARACTER_ONLY.Source§impl<T> RDebug for Twhere
T: Debug,
impl<T> RDebug for Twhere
T: Debug,
Source§impl<T> SizeHint for Twhere
T: ?Sized,
impl<T> SizeHint for Twhere
T: ?Sized,
Source§default fn lower_bound(&self) -> usize
default fn lower_bound(&self) -> usize
core_io_internals)[u8; 12] could return any value between 0 and
12 inclusively as a correct implementation. Read moreSource§impl<T> SizedTypeProperties for T
impl<T> SizedTypeProperties for T
Source§#[doc(hidden)]const SIZE: usize = _
#[doc(hidden)]const SIZE: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGN: usize = _
#[doc(hidden)]const ALIGN: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGNMENT: Alignment = _
#[doc(hidden)]const ALIGNMENT: Alignment = _
ptr_alignment_type)Source§#[doc(hidden)]const IS_ZST: bool = _
#[doc(hidden)]const IS_ZST: bool = _
sized_type_properties)Source§#[doc(hidden)]const LAYOUT: Layout = _
#[doc(hidden)]const LAYOUT: Layout = _
sized_type_properties)Source§#[doc(hidden)]const MAX_SLICE_LEN: usize = _
#[doc(hidden)]const MAX_SLICE_LEN: usize = _
sized_type_properties)[Self]. Read moreLayout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 24 bytes