This is an automated email from the ASF dual-hosted git repository.
paleolimbot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-nanoarrow.git
The following commit(s) were added to refs/heads/main by this push:
new 741826a feat(r): Add conversion from integer type to `character()`
(#345)
741826a is described below
commit 741826a2ad9a8fdfcd527a1df8af49711f0e77e7
Author: Dewey Dunnington <[email protected]>
AuthorDate: Tue Jan 2 09:09:58 2024 -0400
feat(r): Add conversion from integer type to `character()` (#345)
Closes #324.
---
r/src/convert_array.c | 16 +++++++++++++---
r/src/materialize_chr.h | 29 +++++++++++++++++++++++++++++
r/tests/testthat/test-convert-array.R | 35 ++++++++++++++++++++++++++++++-----
3 files changed, 72 insertions(+), 8 deletions(-)
diff --git a/r/src/convert_array.c b/r/src/convert_array.c
index 375bfa0..ac5326a 100644
--- a/r/src/convert_array.c
+++ b/r/src/convert_array.c
@@ -108,16 +108,26 @@ static SEXP convert_array_chr(SEXP array_xptr, SEXP
ptype_sexp) {
}
// If array_xptr is an extension, use default conversion
- if (schema_view.extension_name.size_bytes > 0) {
+ int source_can_altrep;
+ switch (schema_view.type) {
+ case NANOARROW_TYPE_STRING:
+ case NANOARROW_TYPE_LARGE_STRING:
+ source_can_altrep = 1;
+ break;
+ default:
+ source_can_altrep = 0;
+ }
+
+ if (!source_can_altrep || schema_view.extension_name.size_bytes > 0) {
// Default conversion requires a ptype: resolve it if not already specified
if (ptype_sexp == R_NilValue) {
ptype_sexp =
PROTECT(nanoarrow_c_infer_ptype(array_xptr_get_schema(array_xptr)));
SEXP default_result =
- PROTECT(convert_array_default(array_xptr, VECTOR_TYPE_OTHER,
ptype_sexp));
+ PROTECT(convert_array_default(array_xptr, VECTOR_TYPE_CHR,
ptype_sexp));
UNPROTECT(2);
return default_result;
} else {
- return convert_array_default(array_xptr, VECTOR_TYPE_OTHER, ptype_sexp);
+ return convert_array_default(array_xptr, VECTOR_TYPE_CHR, ptype_sexp);
}
}
diff --git a/r/src/materialize_chr.h b/r/src/materialize_chr.h
index 2d57fdc..dfe9823 100644
--- a/r/src/materialize_chr.h
+++ b/r/src/materialize_chr.h
@@ -21,10 +21,17 @@
#include <R.h>
#include <Rinternals.h>
+#include <inttypes.h>
+#include <stdint.h>
+
#include "materialize_common.h"
#include "nanoarrow.h"
static inline int nanoarrow_materialize_chr(struct RConverter* converter) {
+ if (converter->src.array_view->array->dictionary != NULL) {
+ return ENOTSUP;
+ }
+
struct ArrayViewSlice* src = &converter->src;
struct VectorSlice* dst = &converter->dst;
@@ -35,6 +42,28 @@ static inline int nanoarrow_materialize_chr(struct
RConverter* converter) {
}
return NANOARROW_OK;
+ case NANOARROW_TYPE_INT8:
+ case NANOARROW_TYPE_UINT8:
+ case NANOARROW_TYPE_INT16:
+ case NANOARROW_TYPE_UINT16:
+ case NANOARROW_TYPE_INT32:
+ case NANOARROW_TYPE_UINT32:
+ case NANOARROW_TYPE_INT64: {
+ char buf[64];
+ for (R_xlen_t i = 0; i < dst->length; i++) {
+ if (ArrowArrayViewIsNull(src->array_view, src->offset + i)) {
+ SET_STRING_ELT(dst->vec_sexp, dst->offset + i, NA_STRING);
+ } else {
+ int n_chars =
+ snprintf(buf, sizeof(buf), "%" PRId64,
+ ArrowArrayViewGetIntUnsafe(src->array_view, src->offset
+ i));
+ SET_STRING_ELT(dst->vec_sexp, dst->offset + i,
+ Rf_mkCharLenCE(buf, n_chars, CE_UTF8));
+ }
+ }
+ return NANOARROW_OK;
+ }
+
case NANOARROW_TYPE_STRING:
case NANOARROW_TYPE_LARGE_STRING:
break;
diff --git a/r/tests/testthat/test-convert-array.R
b/r/tests/testthat/test-convert-array.R
index 49265a8..5731ce1 100644
--- a/r/tests/testthat/test-convert-array.R
+++ b/r/tests/testthat/test-convert-array.R
@@ -364,6 +364,31 @@ test_that("convert to vector works for valid integer()", {
)
})
+test_that("convert to works for integer() -> character()", {
+ skip_if_not_installed("arrow")
+
+ arrow_int_types <- list(
+ int8 = arrow::int8(),
+ uint8 = arrow::uint8(),
+ int16 = arrow::int16(),
+ uint16 = arrow::uint16(),
+ int32 = arrow::int32(),
+ uint32 = arrow::uint32(),
+ int64 = arrow::int64()
+ )
+
+ ints <- c(NA, 0:10)
+ for (nm in names(arrow_int_types)) {
+ expect_identical(
+ convert_array(
+ as_nanoarrow_array(ints, schema = arrow_int_types[[!!nm]]),
+ character()
+ ),
+ as.character(ints)
+ )
+ }
+})
+
test_that("convert to vector works for null -> logical()", {
array <- nanoarrow_array_init(na_na())
array$length <- 10
@@ -636,8 +661,8 @@ test_that("convert to vector works for character()", {
# check an array that we can't convert
expect_error(
- convert_array(as_nanoarrow_array(1:5), character()),
- "Can't convert array <int32> to R vector of type character"
+ convert_array(as_nanoarrow_array(1:5), list()),
+ "Can't convert array <int32> to R vector of type list"
)
})
@@ -788,7 +813,7 @@ test_that("convert to vector works for list ->
vctrs::list_of", {
# With bad ptype
expect_error(
- convert_array(array_list, vctrs::list_of(.ptype = character())),
+ convert_array(array_list, vctrs::list_of(.ptype = list())),
"Can't convert `item`"
)
@@ -825,7 +850,7 @@ test_that("convert to vector works for large_list ->
vctrs::list_of", {
# With bad ptype
expect_error(
- convert_array(array_list, vctrs::list_of(.ptype = character())),
+ convert_array(array_list, vctrs::list_of(.ptype = list())),
"Can't convert `item`"
)
})
@@ -854,7 +879,7 @@ test_that("convert to vector works for fixed_size_list ->
vctrs::list_of", {
# With bad ptype
expect_error(
- convert_array(array_list, vctrs::list_of(.ptype = character())),
+ convert_array(array_list, vctrs::list_of(.ptype = list())),
"Can't convert `item`"
)
})