Skip to content

Commit

Permalink
feat: add as.charactor.Series (pola-rs#162)
Browse files Browse the repository at this point in the history
* feat: add internal method `Series$to_fmt_char`

* feat: add `as.charactor.Series`

* test: add more tests
  • Loading branch information
eitsupi authored Apr 22, 2023
1 parent 2be9d5d commit 71e4e58
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 8 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ S3method(.DollarNames,When)
S3method(.DollarNames,WhenThen)
S3method(.DollarNames,WhenThenThen)
S3method(.DollarNames,method_environment)
S3method(as.character,Series)
S3method(as.data.frame,DataFrame)
S3method(as.data.frame,LazyFrame)
S3method(as.list,Expr)
Expand Down
2 changes: 2 additions & 0 deletions R/extendr-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,8 @@ Series$series_equal <- function(other, null_equal, strict) .Call(wrap__Series__s

Series$get_fmt <- function(index, str_length) .Call(wrap__Series__get_fmt, self, index, str_length)

Series$to_fmt_char <- function(str_length) .Call(wrap__Series__to_fmt_char, self, str_length)

Series$compare <- function(other, op) .Call(wrap__Series__compare, self, other, op)

Series$rep <- function(n, rechunk) .Call(wrap__Series__rep, self, n, rechunk)
Expand Down
19 changes: 19 additions & 0 deletions R/s3_methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,25 @@ max.LazyFrame = function(x, ...) x$max()
#' @noRd
as.vector.Series = function(x, mode) x$to_vector()

#' @param x Series
#' @param format a logical. If `TRUE`, the Series will be formatted.
#' @param str_length an integer. If `format = TRUE`,
#' utf8 or categorical type Series will be formatted to a string of this length.
#' @examples
#' s = pl$Series(c("foo", "barbaz"))
#' as.character(s)
#' as.character(s, format = TRUE)
#' as.character(s, format = TRUE, str_length = 3)
#' @export
as.character.Series = function(x, ..., format = FALSE, str_length = 15) {
if (isTRUE(format)) {
.pr$Series$to_fmt_char(x, str_length = str_length)
} else {
x$to_vector() |>
as.character()
}
}

#' @export
#' @noRd
max.Series = function(x, ...) x$max()
Expand Down
9 changes: 9 additions & 0 deletions src/rust/src/series.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,15 @@ impl Series {
}
}

fn to_fmt_char(&self, str_length: u32) -> Vec<String> {
let len = self.0.len();
let mut res = Vec::with_capacity(len);
for i in 0..len {
res.push(self.get_fmt(i.try_into().expect("usize>u32"), str_length));
}
res
}

pub fn compare(&self, other: &Series, op: String) -> List {
//try cast other to self, downcast(dc) to chunkedarray and compare with operator(op) elementwise
macro_rules! comp {
Expand Down
157 changes: 157 additions & 0 deletions tests/testthat/_snaps/s3_methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Series as.character v=a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z

Code
as.character(pl$Series(v))
Output
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x" "y" "z"

---

Code
as.character(pl$Series(v), format = TRUE)
Output
[1] "\"a\"" "\"b\"" "\"c\"" "\"d\"" "\"e\"" "\"f\"" "\"g\"" "\"h\"" "\"i\""
[10] "\"j\"" "\"k\"" "\"l\"" "\"m\"" "\"n\"" "\"o\"" "\"p\"" "\"q\"" "\"r\""
[19] "\"s\"" "\"t\"" "\"u\"" "\"v\"" "\"w\"" "\"x\"" "\"y\"" "\"z\""

---

Code
as.character(pl$Series(v), format = TRUE, str_length = 2)
Output
[1] "\"a…" "\"b…" "\"c…" "\"d…" "\"e…" "\"f…" "\"g…" "\"h…" "\"i…" "\"j…"
[11] "\"k…" "\"l…" "\"m…" "\"n…" "\"o…" "\"p…" "\"q…" "\"r…" "\"s…" "\"t…"
[21] "\"u…" "\"v…" "\"w…" "\"x…" "\"y…" "\"z…"

# Series as.character v=1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Code
as.character(pl$Series(v))
Output
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"

---

Code
as.character(pl$Series(v), format = TRUE)
Output
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"

---

Code
as.character(pl$Series(v), format = TRUE, str_length = 2)
Output
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"

---

Code
as.character(pl$Series(v))
Output
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"

---

Code
as.character(pl$Series(v), format = TRUE)
Output
[1] "1.0" "2.0" "3.0" "4.0" "5.0" "6.0" "7.0" "8.0" "9.0" "10.0"

---

Code
as.character(pl$Series(v), format = TRUE, str_length = 2)
Output
[1] "1.0" "2.0" "3.0" "4.0" "5.0" "6.0" "7.0" "8.0" "9.0" "10.0"

# Series as.character v=bar

Code
as.character(pl$Series(v))
Output
[1] "bar"

---

Code
as.character(pl$Series(v), format = TRUE)
Output
[1] "\"bar\""

---

Code
as.character(pl$Series(v), format = TRUE, str_length = 2)
Output
[1] "\"b…"

# Series as.character v=TRUE, FALSE

Code
as.character(pl$Series(v))
Output
[1] "TRUE" "FALSE"

---

Code
as.character(pl$Series(v), format = TRUE)
Output
[1] "true" "false"

---

Code
as.character(pl$Series(v), format = TRUE, str_length = 2)
Output
[1] "true" "false"

# Series as.character v=1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26

Code
as.character(pl$Series(v))
Output
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x" "y" "z"

---

Code
as.character(pl$Series(v), format = TRUE)
Output
[1] "\"a\"" "\"b\"" "\"c\"" "\"d\"" "\"e\"" "\"f\"" "\"g\"" "\"h\"" "\"i\""
[10] "\"j\"" "\"k\"" "\"l\"" "\"m\"" "\"n\"" "\"o\"" "\"p\"" "\"q\"" "\"r\""
[19] "\"s\"" "\"t\"" "\"u\"" "\"v\"" "\"w\"" "\"x\"" "\"y\"" "\"z\""

---

Code
as.character(pl$Series(v), format = TRUE, str_length = 2)
Output
[1] "\"a…" "\"b…" "\"c…" "\"d…" "\"e…" "\"f…" "\"g…" "\"h…" "\"i…" "\"j…"
[11] "\"k…" "\"l…" "\"m…" "\"n…" "\"o…" "\"p…" "\"q…" "\"r…" "\"s…" "\"t…"
[21] "\"u…" "\"v…" "\"w…" "\"x…" "\"y…" "\"z…"

# Series as.character v=foooo , barrrrr

Code
as.character(pl$Series(v))
Output
[1] "foooo" "barrrrr"

---

Code
as.character(pl$Series(v), format = TRUE)
Output
[1] "\"foooo\"" "\"barrrrr\""

---

Code
as.character(pl$Series(v), format = TRUE, str_length = 2)
Output
[1] "\"f…" "\"b…"

28 changes: 21 additions & 7 deletions tests/testthat/test-s3_methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,31 @@ patrick::with_parameters_test_that("Series",
.cases = make_cases()
)

vecs_to_test = list(
letters,
1:10,
as.double(1:10),
c("foo" = "bar"),
c(TRUE, FALSE),
as.factor(letters),
c("foooo", "barrrrr")
)

patrick::with_parameters_test_that("Series as.vector",
{
expect_equal(as.vector(pl$Series(v)), v, ignore_attr = TRUE)
},
v = list(
letters,
1:10,
c("foo" = "bar"),
c(TRUE, FALSE),
as.factor(letters)
)
v = vecs_to_test
)

patrick::with_parameters_test_that("Series as.character",
{
expect_equal(as.character(pl$Series(v)), as.character(v), ignore_attr = TRUE)
expect_snapshot(as.character(pl$Series(v)), cran = TRUE)
expect_snapshot(as.character(pl$Series(v), format = TRUE), cran = TRUE)
expect_snapshot(as.character(pl$Series(v), format = TRUE, str_length = 2), cran = TRUE)
},
v = vecs_to_test
)

test_that("drop_nulls", {
Expand Down
10 changes: 9 additions & 1 deletion tests/testthat/test-series.R
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ test_that("Backward compatibility: to_r_vector", {
expect_identical(pl$Series(1:3)$to_r_vector(), 1:3)
})

test_that("internal method get_fmt", {
test_that("internal method get_fmt and to_fmt_char", {
s_1 <- pl$Series(c("foo", "bar"))
expect_equal(
.pr$Series$get_fmt(s_1, index = 1, str_length = 3),
Expand All @@ -495,4 +495,12 @@ test_that("internal method get_fmt", {
.pr$Series$get_fmt(s_1, index = 0, str_length = 100),
'"foo"'
)
expect_equal(
.pr$Series$to_fmt_char(s_1, 3),
c('"fo…', '"ba…')
)
expect_equal(
.pr$Series$to_fmt_char(s_1, 100),
c('"foo"', '"bar"')
)
})

0 comments on commit 71e4e58

Please sign in to comment.