Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add str$to_decimal() #55

Merged
merged 1 commit into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions R/000-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -2644,6 +2644,12 @@ class(`PlRDataType`) <- c("PlRDataType__bundle", "savvy_neopolars__sealed")
}
}

`PlRExpr_str_to_decimal` <- function(self) {
function(`infer_len`) {
.savvy_wrap_PlRExpr(.Call(savvy_PlRExpr_str_to_decimal__impl, `self`, `infer_len`))
}
}

`PlRExpr_str_contains` <- function(self) {
function(`pat`, `literal`, `strict`) {
`pat` <- .savvy_extract_ptr(`pat`, "PlRExpr")
Expand Down Expand Up @@ -3194,6 +3200,7 @@ class(`PlRDataType`) <- c("PlRDataType__bundle", "savvy_neopolars__sealed")
e$`str_zfill` <- `PlRExpr_str_zfill`(ptr)
e$`str_pad_end` <- `PlRExpr_str_pad_end`(ptr)
e$`str_pad_start` <- `PlRExpr_str_pad_start`(ptr)
e$`str_to_decimal` <- `PlRExpr_str_to_decimal`(ptr)
e$`str_contains` <- `PlRExpr_str_contains`(ptr)
e$`str_ends_with` <- `PlRExpr_str_ends_with`(ptr)
e$`str_starts_with` <- `PlRExpr_str_starts_with`(ptr)
Expand Down
21 changes: 21 additions & 0 deletions R/expr-string.R
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,27 @@ expr_str_zfill <- function(alignment) {
wrap()
}

#' Convert a String column into a Decimal column
#'
#' @description
#' This method infers the needed parameters `precision` and `scale`.
#'
#' @param inference_length Number of elements to parse to determine the
#' `precision` and `scale`.
#' @inherit as_polars_expr return
#'
#' @examples
#' df <- pl$DataFrame(
#' numbers = c(
#' "40.12", "3420.13", "120134.19", "3212.98",
#' "12.90", "143.09", "143.9"
#' )
#' )
#' df$with_columns(numbers_decimal = pl$col("numbers")$str$to_decimal())
expr_str_to_decimal <- function(inference_length = 100) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first glance it is unclear what kind of role the number in the first argument plays, so for me it is surprising that this argument is not a named-only argument.

This is fine for now, but we probably need to update Python Polars.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably need to update Python Polars.

I've opened an issue pola-rs/polars#20564

self$`_rexpr`$str_to_decimal(inference_length) |>
wrap()
}

#' Left justify strings
#'
Expand Down
27 changes: 27 additions & 0 deletions man/expr_str_to_decimal.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -2039,6 +2039,11 @@ SEXP savvy_PlRExpr_str_pad_start__impl(SEXP self__, SEXP c_arg__width, SEXP c_ar
return handle_result(res);
}

SEXP savvy_PlRExpr_str_to_decimal__impl(SEXP self__, SEXP c_arg__infer_len) {
SEXP res = savvy_PlRExpr_str_to_decimal__ffi(self__, c_arg__infer_len);
return handle_result(res);
}

SEXP savvy_PlRExpr_str_contains__impl(SEXP self__, SEXP c_arg__pat, SEXP c_arg__literal, SEXP c_arg__strict) {
SEXP res = savvy_PlRExpr_str_contains__ffi(self__, c_arg__pat, c_arg__literal, c_arg__strict);
return handle_result(res);
Expand Down Expand Up @@ -2917,6 +2922,7 @@ static const R_CallMethodDef CallEntries[] = {
{"savvy_PlRExpr_str_zfill__impl", (DL_FUNC) &savvy_PlRExpr_str_zfill__impl, 2},
{"savvy_PlRExpr_str_pad_end__impl", (DL_FUNC) &savvy_PlRExpr_str_pad_end__impl, 3},
{"savvy_PlRExpr_str_pad_start__impl", (DL_FUNC) &savvy_PlRExpr_str_pad_start__impl, 3},
{"savvy_PlRExpr_str_to_decimal__impl", (DL_FUNC) &savvy_PlRExpr_str_to_decimal__impl, 2},
{"savvy_PlRExpr_str_contains__impl", (DL_FUNC) &savvy_PlRExpr_str_contains__impl, 4},
{"savvy_PlRExpr_str_ends_with__impl", (DL_FUNC) &savvy_PlRExpr_str_ends_with__impl, 2},
{"savvy_PlRExpr_str_starts_with__impl", (DL_FUNC) &savvy_PlRExpr_str_starts_with__impl, 2},
Expand Down
1 change: 1 addition & 0 deletions src/rust/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,7 @@ SEXP savvy_PlRExpr_str_strip_chars_start__ffi(SEXP self__, SEXP c_arg__matches);
SEXP savvy_PlRExpr_str_zfill__ffi(SEXP self__, SEXP c_arg__alignment);
SEXP savvy_PlRExpr_str_pad_end__ffi(SEXP self__, SEXP c_arg__width, SEXP c_arg__fillchar);
SEXP savvy_PlRExpr_str_pad_start__ffi(SEXP self__, SEXP c_arg__width, SEXP c_arg__fillchar);
SEXP savvy_PlRExpr_str_to_decimal__ffi(SEXP self__, SEXP c_arg__infer_len);
SEXP savvy_PlRExpr_str_contains__ffi(SEXP self__, SEXP c_arg__pat, SEXP c_arg__literal, SEXP c_arg__strict);
SEXP savvy_PlRExpr_str_ends_with__ffi(SEXP self__, SEXP c_arg__sub);
SEXP savvy_PlRExpr_str_starts_with__ffi(SEXP self__, SEXP c_arg__sub);
Expand Down
5 changes: 5 additions & 0 deletions src/rust/src/expr/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ impl PlRExpr {
Ok(self.inner.clone().str().pad_start(width, fillchar).into())
}

fn str_to_decimal(&self, infer_len: NumericScalar) -> Result<Self> {
let infer_len = <Wrap<usize>>::try_from(infer_len)?.0;
Ok(self.inner.clone().str().to_decimal(infer_len).into())
}

fn str_contains(&self, pat: &PlRExpr, literal: bool, strict: bool) -> Result<Self> {
if literal {
Ok(self
Expand Down
16 changes: 16 additions & 0 deletions tests/testthat/test-expr-string.R
Original file line number Diff line number Diff line change
Expand Up @@ -1008,3 +1008,19 @@ test_that("$str$extract_many works", {
pl$DataFrame(values = list("disco", c("rhap", "ody")))
)
})

# TODO: uncomment when https://github.com/pola-rs/polars/issues/20556 is solved
# test_that("to_decimal", {
# df <- pl$DataFrame(
# x = c(
# "40.12", "3420.13", "120134.19", "3212.98",
# "12.90", "143.09", "143.9"
# )
# )
# expect_equal(
# df$select(pl$col("x")$str$to_decimal()),
# pl$DataFrame(x = c(
# 40.12, 3420.13, 120134.19, 3212.98, 12.90, 143.09, 143.9
# ), .schema_overrides = list(x = pl$Decimal(scale = 2)))
# )
# })