diff --git a/r/src/type_infer.cpp b/r/src/type_infer.cpp index 616be0467f940..e30d0e1288717 100644 --- a/r/src/type_infer.cpp +++ b/r/src/type_infer.cpp @@ -165,8 +165,13 @@ std::shared_ptr InferArrowTypeFromVector(SEXP x) { cpp11::stop( "Requires at least one element to infer the values' type of a list vector"); } - - ptype = VECTOR_ELT(x, 0); + // Iterate through the vector until we get a non-null result + for (R_xlen_t i = 0; i < XLENGTH(x); i++) { + ptype = VECTOR_ELT(x, i); + if (!Rf_isNull(ptype)) { + break; + } + } } return arrow::list(InferArrowType(ptype)); @@ -198,6 +203,8 @@ std::shared_ptr InferArrowType(SEXP x) { return InferArrowTypeFromVector(x); case VECSXP: return InferArrowTypeFromVector(x); + case NILSXP: + return null(); default: cpp11::stop("Cannot infer type from vector"); } diff --git a/r/tests/testthat/test-type.R b/r/tests/testthat/test-type.R index d7c6da0792cf7..14f0ea7a8d580 100644 --- a/r/tests/testthat/test-type.R +++ b/r/tests/testthat/test-type.R @@ -293,3 +293,19 @@ test_that("type() is deprecated", { ) expect_equal(a_type, a$type) }) + +test_that("infer_type() infers type for lists starting with NULL - ARROW-17639", { + null_start_list <- list(NULL, c(2, 3), c(4, 5)) + + expect_equal( + infer_type(null_start_list), + list_of(float64()) + ) + + totally_null_list <- list(NULL, NULL, NULL) + + expect_equal( + infer_type(totally_null_list), + list_of(null()) + ) +})