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

Implement $name$to_lowercase() and $name$to_uppercase() #529

Merged
merged 4 commits into from
Nov 21, 2023
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
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
- New method `$ungroup()` for `GroupBy` and `LazyGroupBy` (#522).
- New method `$rolling()` to apply an Expr over a rolling window based on
date/datetime/numeric indices (#470).
- New methods `$name$to_lowercase()` and `$name$to_uppercase()` to transform
variable names (#529).
- New methods of the Expressions class, `$floor_div()`, `$mod()`, `$eq_missing()`
and `$neq_missing()`. The base R operators `%/%` and `%%` for Expressions are
now translated to `$floor_div()` and `$mod()` (#523).
Expand Down
62 changes: 42 additions & 20 deletions R/expr__name.R
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
#' Add a suffix to a column name
#' @keywords Expr
#'
#' @param suffix Suffix to be added to column name(s)
#' @name ExprName_suffix
#' @rdname ExprName_suffix
#' @return Expr
#' @aliases suffix
#' @seealso
#' [`$prefix()`][ExprName_prefix] to add a prefix
#' @name ExprName_suffix
#' @examples
#' dat = pl$DataFrame(mtcars)
#'
Expand All @@ -17,19 +14,17 @@
#' pl$col("cyl", "drat")$name$suffix("_bar")
#' )
ExprName_suffix = function(suffix) {
.pr$Expr$name_suffix(self, suffix)
.pr$Expr$name_suffix(self, suffix) |>
unwrap("in $name$suffix():")
}

#' Add a prefix to a column name
#' @keywords Expr
#'
#' @param prefix Prefix to be added to column name(s)
#' @name ExprName_prefix
#' @rdname ExprName_prefix
#' @return Expr
#' @aliases prefix
#' @seealso
#' [`$suffix()`][ExprName_suffix] to add a suffix
#' @name ExprName_prefix
#' @examples
#' dat = pl$DataFrame(mtcars)
#'
Expand All @@ -39,32 +34,30 @@ ExprName_suffix = function(suffix) {
#' pl$col("cyl", "drat")$name$prefix("bar_")
#' )
ExprName_prefix = function(prefix) {
.pr$Expr$name_prefix(self, prefix)
.pr$Expr$name_prefix(self, prefix) |>
unwrap("in $name$prefix():")
}

# TODO contribute pypolars keep_name example does not showcase an example where the name changes

#' Keep the original root name of the expression.
#'
#' @keywords Expr
#' @return Expr
#' @aliases keep_name
#' @name ExprName_keep
#' @docType NULL
#' @format NULL
#' @format NULL
#' @examples
#' pl$DataFrame(list(alice = 1:3))$select(pl$col("alice")$alias("bob")$name$keep())
ExprName_keep = function() {
.pr$Expr$name_keep(self)
.pr$Expr$name_keep(self) |>
unwrap("in $name$keep():")
}

# TODO contribute polars, $name$map unwrap user function errors instead of passing them back

#' Map alias of expression with an R function
#'
#' @param fun an R function which takes a string as input and return a string
#' Rename the output of an expression by mapping a function over the root name.
#'
#' @description Rename the output of an expression by mapping a function over the root name.
#' @keywords Expr
#' @param fun an R function which takes a string as input and return a string
#' @return Expr
#' @name ExprName_map
#' @examples
Expand All @@ -83,5 +76,34 @@ ExprName_map = function(fun) {
}
if (!is.function(fun)) pstop(err = "$name$map() fun must be a function")
if (length(formals(fun)) == 0) pstop(err = "$name$map() fun must take at least one parameter")
.pr$Expr$name_map(self, fun)
.pr$Expr$name_map(self, fun) |>
unwrap("in $name$map():")
}


#' Make the root column name lowercase
#'
#' Due to implementation constraints, this method can only be called as the last
#' expression in a chain.
#'
#' @return Expr
#' @name ExprName_to_lowercase
#' @examples
#' pl$DataFrame(Alice = 1:3)$with_columns(pl$col("Alice")$name$to_lowercase())
ExprName_to_lowercase = function() {
.pr$Expr$name_to_lowercase(self) |>
unwrap("in $name$to_lowercase():")
}

#' Make the root column name uppercase
#'
#' @inherit ExprName_to_lowercase description
#'
#' @return Expr
#' @name ExprName_to_uppercase
#' @examples
#' pl$DataFrame(Alice = 1:3)$with_columns(pl$col("Alice")$name$to_uppercase())
ExprName_to_uppercase = function() {
.pr$Expr$name_to_uppercase(self) |>
unwrap("in $name$to_uppercase():")
}
4 changes: 4 additions & 0 deletions R/extendr-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,10 @@ Expr$name_suffix <- function(suffix) .Call(wrap__Expr__name_suffix, self, suffix

Expr$name_prefix <- function(prefix) .Call(wrap__Expr__name_prefix, self, prefix)

Expr$name_to_lowercase <- function() .Call(wrap__Expr__name_to_lowercase, self)

Expr$name_to_uppercase <- function() .Call(wrap__Expr__name_to_uppercase, self)

Expr$name_map <- function(lambda) .Call(wrap__Expr__name_map, self, lambda)

Expr$str_len_bytes <- function() .Call(wrap__Expr__str_len_bytes, self)
Expand Down
2 changes: 0 additions & 2 deletions man/ExprName_keep.Rd

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

1 change: 0 additions & 1 deletion man/ExprName_map.Rd

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

2 changes: 0 additions & 2 deletions man/ExprName_prefix.Rd

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

2 changes: 0 additions & 2 deletions man/ExprName_suffix.Rd

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

15 changes: 15 additions & 0 deletions man/ExprName_to_lowercase.Rd

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

15 changes: 15 additions & 0 deletions man/ExprName_to_uppercase.Rd

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

24 changes: 16 additions & 8 deletions src/rust/src/lazy/dsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1796,19 +1796,27 @@ impl Expr {
}

// name methods
pub fn name_keep(&self) -> Self {
self.0.clone().name().keep().into()
pub fn name_keep(&self) -> RResult<Self> {
Ok(self.0.clone().name().keep().into())
}

fn name_suffix(&self, suffix: String) -> Self {
self.0.clone().name().suffix(suffix.as_str()).into()
fn name_suffix(&self, suffix: String) -> RResult<Self> {
Ok(self.0.clone().name().suffix(suffix.as_str()).into())
}

fn name_prefix(&self, prefix: String) -> Self {
self.0.clone().name().prefix(prefix.as_str()).into()
fn name_prefix(&self, prefix: String) -> RResult<Self> {
Ok(self.0.clone().name().prefix(prefix.as_str()).into())
}

pub fn name_map(&self, lambda: Robj) -> Self {
fn name_to_lowercase(&self) -> RResult<Self> {
Ok(self.0.clone().name().to_lowercase().into())
}

fn name_to_uppercase(&self) -> RResult<Self> {
Ok(self.0.clone().name().to_uppercase().into())
}

pub fn name_map(&self, lambda: Robj) -> RResult<Self> {
//find a way not to push lambda everytime to main thread handler
//safety only accessed in main thread, can be temp owned by other threads
let probj = ParRObj(lambda);
Expand Down Expand Up @@ -1856,7 +1864,7 @@ impl Expr {
.map(|str| str.to_string())
};

self.clone().0.name().map(f).into()
Ok(self.clone().0.name().map(f).into())
}

//string methods
Expand Down
15 changes: 15 additions & 0 deletions tests/testthat/test-expr_name.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
test_that("name to_lowercase", {
df = pl$DataFrame(Var1 = 1, vAR2 = 2)
expect_equal(
names(df$select(pl$all()$name$to_lowercase())),
c("var1", "var2")
)
})

test_that("name to_uppercase", {
df = pl$DataFrame(Var1 = 1, vAR2 = 2)
expect_equal(
names(df$select(pl$all()$name$to_uppercase())),
c("VAR1", "VAR2")
)
})
Loading