Skip to content

Commit

Permalink
Internal improvements.
Browse files Browse the repository at this point in the history
  • Loading branch information
NicChr committed Sep 23, 2024
1 parent b13371d commit 41e1d80
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 10 deletions.
2 changes: 1 addition & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
S3method(base::as.character,vctrs_rcrd)
S3method(base::as.double,integer64)
S3method(base::as.integer,integer64)
S3method(base::as.numeric,integer64)
S3method(collapse::fmax,integer64)
S3method(collapse::fmean,integer64)
S3method(collapse::fmedian,integer64)
S3method(collapse::fmin,integer64)
S3method(collapse::fnobs,integer64)
S3method(collapse::fnth,integer64)
S3method(collapse::fsd,integer64)
S3method(collapse::fsum,integer64)
S3method(collapse::funique,POSIXlt)
S3method(collapse::funique,vctrs_rcrd)
S3method(collapse::fvar,integer64)
Expand Down
4 changes: 4 additions & 0 deletions R/cpp11.R
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ cpp_int64_to_double <- function(x) {
.Call(`_cheapr_cpp_int64_to_double`, x)
}

cpp_int64_to_numeric <- function(x) {
.Call(`_cheapr_cpp_int64_to_numeric`, x)
}

cpp_numeric_to_int64 <- function(x) {
.Call(`_cheapr_cpp_numeric_to_int64`, x)
}
Expand Down
2 changes: 1 addition & 1 deletion R/factors.R
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ factor_ <- function(
}
is_int64 <- inherits(x, "integer64")
if (is_int64){
x <- as.double(x)
x <- cpp_int64_to_numeric(x)
}
if (is.null(levels)){
lvls <- collapse::funique(x, sort = order, na.last = TRUE)
Expand Down
19 changes: 11 additions & 8 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -145,30 +145,33 @@ funique.POSIXlt <- function(x, sort = FALSE, ...){
as.double.integer64 <- function(x, ...){
cpp_int64_to_double(x)
}
#' @exportS3Method base::as.numeric
as.numeric.integer64 <- as.double.integer64
#' @exportS3Method base::as.integer
as.integer.integer64 <- function(x, ...){
cpp_int64_to_int(x)
}

# collapse methods for integer64
# They are obviously slow but at least result is correct

#' @exportS3Method collapse::fsum
fsum.integer64 <- function(x, ...){
collapse::fsum(cpp_int64_to_numeric(x), ...)
}
#' @exportS3Method collapse::fmin
fmin.integer64 <- function(x, ...){
cpp_numeric_to_int64(collapse::fmin(as.double(x), ...))
cpp_numeric_to_int64(collapse::fmin(cpp_int64_to_numeric(x), ...))
}
#' @exportS3Method collapse::fmax
fmax.integer64 <- function(x, ...){
cpp_numeric_to_int64(collapse::fmax(as.double(x), ...))
cpp_numeric_to_int64(collapse::fmax(cpp_int64_to_numeric(x), ...))
}
#' @exportS3Method collapse::fmean
fmean.integer64 <- function(x, ...){
collapse::fmean(as.double(x), ...)
collapse::fmean(cpp_int64_to_numeric(x), ...)
}
#' @exportS3Method collapse::fmedian
fmedian.integer64 <- function(x, ...){
collapse::fmedian(as.double(x), ...)
collapse::fmedian(cpp_int64_to_numeric(x), ...)
}
#' @exportS3Method collapse::fvar
fvar.integer64 <- function(x, ...){
Expand All @@ -180,11 +183,11 @@ fsd.integer64 <- function(x, ...){
}
#' @exportS3Method collapse::fnth
fnth.integer64 <- function(x, ...){
collapse::fnth(as.double(x), ...)
collapse::fnth(cpp_int64_to_numeric(x), ...)
}
#' @exportS3Method collapse::fnobs
fnobs.integer64 <- function(x, ...){
collapse::fnobs(as.double(x), ...)
collapse::fnobs(cpp_int64_to_numeric(x), ...)
}

n_dots <- function(...){
Expand Down
8 changes: 8 additions & 0 deletions src/cpp11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ extern "C" SEXP _cheapr_cpp_int64_to_double(SEXP x) {
END_CPP11
}
// int64.cpp
SEXP cpp_int64_to_numeric(SEXP x);
extern "C" SEXP _cheapr_cpp_int64_to_numeric(SEXP x) {
BEGIN_CPP11
return cpp11::as_sexp(cpp_int64_to_numeric(cpp11::as_cpp<cpp11::decay_t<SEXP>>(x)));
END_CPP11
}
// int64.cpp
SEXP cpp_numeric_to_int64(SEXP x);
extern "C" SEXP _cheapr_cpp_numeric_to_int64(SEXP x) {
BEGIN_CPP11
Expand Down Expand Up @@ -495,6 +502,7 @@ static const R_CallMethodDef CallEntries[] = {
{"_cheapr_cpp_gcd2_vectorised", (DL_FUNC) &_cheapr_cpp_gcd2_vectorised, 4},
{"_cheapr_cpp_int64_to_double", (DL_FUNC) &_cheapr_cpp_int64_to_double, 1},
{"_cheapr_cpp_int64_to_int", (DL_FUNC) &_cheapr_cpp_int64_to_int, 1},
{"_cheapr_cpp_int64_to_numeric", (DL_FUNC) &_cheapr_cpp_int64_to_numeric, 1},
{"_cheapr_cpp_int_sequence", (DL_FUNC) &_cheapr_cpp_int_sequence, 3},
{"_cheapr_cpp_is_na", (DL_FUNC) &_cheapr_cpp_is_na, 1},
{"_cheapr_cpp_lag", (DL_FUNC) &_cheapr_cpp_lag, 5},
Expand Down
22 changes: 22 additions & 0 deletions src/int64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,28 @@ SEXP cpp_int64_to_double(SEXP x){
return out;
}

// Convert 64-bit integer to int if possible, otherwise double

[[cpp11::register]]
SEXP cpp_int64_to_numeric(SEXP x){
if (!is_int64(x)){
Rf_error("x must be an integer64");
}
R_xlen_t n = Rf_xlength(x);

long long *p_x = INTEGER64_PTR(x);

bool maybe_int = true;
long long int int_max = integer_max_;
for (R_xlen_t i = 0; i < n; ++i){
if (!cheapr_is_na_int64(p_x[i]) && std::llabs(p_x[i]) > int_max){
maybe_int = false;
break;
}
}
return maybe_int ? cpp_int64_to_int(x) : cpp_int64_to_double(x);
}

// The reverse operation
// Convert any numeric vector into 64-integer vec
// Very much an internal function as cheapr never explicitly outputs
Expand Down

0 comments on commit 41e1d80

Please sign in to comment.