Skip to content

Commit

Permalink
Bug fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
NicChr committed Sep 23, 2024
1 parent 44efcad commit f2f91a5
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 157 deletions.
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ supported in any sequence functions or in the 'set_math' functions.

* `lag_` now uses `memmove` where possible.

* Fixed an issue where `lag_(x)` was materialising x twice if x was an altrep
* Fixed an issue where `lag_(x)` was materialising x twice if x was an ALTREP
integer sequence.

# cheapr 0.9.3 (29-Jul-2024)
Expand Down
69 changes: 60 additions & 9 deletions R/extras.R
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,64 @@ cut_numeric <- function(x, breaks, labels = NULL, include.lowest = FALSE,
}
#' @export
#' @rdname extras
cut.integer64 <- function(x, breaks, labels = NULL, include.lowest = FALSE,
right = TRUE, dig.lab = 3L, ordered_result = FALSE, ...){
cut_numeric(as.double(x), breaks = breaks,
labels = labels, include.lowest = include.lowest,
right = right, dig.lab = dig.lab, ordered_result = ordered_result,
...)

cut.integer64 <- function(x, ...){
cut_numeric(cpp_int64_to_numeric(x), ...)
# if (!is.numeric(x))
# stop("'x' must be numeric")
# if (length(breaks) == 1L) {
# if (is.na(breaks) || breaks < 2L)
# stop("invalid number of intervals")
# nb <- as.integer(breaks + 1)
# dx <- diff(rx <- as.double(range(x, na.rm = TRUE)))
#
# if (isTRUE(dx == 0)) {
# dx <- if (rx[1L] != 0)
# abs(rx[1L])
# else 1
# breaks <- seq.int(rx[1L] - dx/1000, rx[2L] + dx/1000,
# length.out = nb)
# }
# else {
# breaks <- seq.int(rx[1L], rx[2L], length.out = nb)
# breaks[c(1L, nb)] <- c(rx[1L] - dx/1000, rx[2L] +
# dx/1000)
# }
# }
# else nb <- length(breaks <- sort(as.double(breaks)))
# if (anyDuplicated(breaks))
# stop("'breaks' are not unique")
# codes.only <- FALSE
# if (is.null(labels)) {
# for (dig in dig.lab:max(12L, dig.lab)) {
# ch.br <- cpp_format_numeric_as_int64(breaks)
# ch.br[na_find(ch.br)] <- "NA"
# if (ok <- all(ch.br[-1L] != ch.br[-nb]))
# break
# }
# labels <- if (ok)
# paste0(if (right)
# "("
# else "[", ch.br[-nb], ",", ch.br[-1L], if (right)
# "]"
# else ")")
# else paste0("Range_", seq_len(nb - 1L))
# if (ok && include.lowest) {
# if (right)
# substr(labels[1L], 1L, 1L) <- "["
# else substring(labels[nb - 1L], nchar(labels[nb -
# 1L], "c")) <- "]"
# }
# }
# else if (is.logical(labels) && !labels)
# codes.only <- TRUE
# else if (length(labels) != nb - 1L)
# stop("number of intervals and length of 'labels' differ")
# code <- .bincode(cpp_int64_to_numeric(x), breaks, right, include.lowest)
# if (!codes.only) {
# levels(code) <- as.character(labels)
# class(code) <- c(if (ordered_result) "ordered" else character(0), "factor")
# }
# code
}
#' @export
#' @rdname extras
Expand Down Expand Up @@ -180,8 +231,8 @@ deframe_ <- function(x){
}
#' @export
#' @rdname extras
sample_ <- function(x, size = cpp_vec_length(x), replace = FALSE, prob = NULL){
sset(x, sample.int(cpp_vec_length(x), size, replace, prob))
sample_ <- function(x, size = vector_length(x), replace = FALSE, prob = NULL){
sset(x, sample.int(vector_length(x), size, replace, prob))
}
#' @export
#' @rdname extras
Expand Down
4 changes: 2 additions & 2 deletions R/scalars.R
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ na_count <- num_na
#' @export
na_find <- function(x, invert = FALSE){
if (invert){
which_na(x)
} else {
which_not_na(x)
} else {
which_na(x)
}
}
#' @rdname scalars
Expand Down
5 changes: 5 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ as.integer.integer64 <- function(x, ...){

#' @exportS3Method collapse::fsum
fsum.integer64 <- function(x, g = NULL, ...){

## The statement is here because
## when there are groups, collapse::fsum
## errors when there is a 32-bit int overflow

if (is.null(g)){
collapse::fsum(cpp_int64_to_numeric(x), ...)
} else {
Expand Down
7 changes: 3 additions & 4 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
* Updated to version 0.9.3

* Have fixed the issues listed at https://cran.r-project.org/web/checks/check_results_cheapr.html
* Updated to version 0.9.5

* Checked and passed using rhub v2.0.0 in the following environments:

## Test environments
- R-hubv2 windows (R-devel)
- R-hubv2 linux (R-devel)
- R-hubv2 macos (R-devel)
- R-hubv2 macos-arm64 (R-devel)
- R-hubv2 clang-asan
- R-hubv2 ubuntu-gcc12
- R-hubv2 ubuntu-clang

Additionally checked on win-builder.r-project.org:

Expand Down
13 changes: 2 additions & 11 deletions man/extras.Rd

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

56 changes: 43 additions & 13 deletions src/int64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,56 @@ SEXP cpp_int64_to_double(SEXP x){
return out;
}

// Can all numbers be safely converted to 32-bit int?

bool cpp_all_integerable(SEXP x, int shift = 0){
R_xlen_t n = Rf_xlength(x);
bool out = true;

switch (TYPEOF(x)){
case LGLSXP:
case INTSXP: {
break;
}
case REALSXP: {
if (is_int64(x)){
long long int *p_x = INTEGER64_PTR(x);
long long int int_max = integer_max_;
long long int shift_ = shift;
for (R_xlen_t i = 0; i < n; ++i){
if (!cheapr_is_na_int64(p_x[i]) && ( (std::llabs(p_x[i]) + shift_) > int_max )){
out = false;
break;
}
}
} else {
double *p_x = REAL(x);
double int_max = integer_max_;
double shift_ = shift;
for (R_xlen_t i = 0; i < n; ++i){
if (!cheapr_is_na_dbl(p_x[i]) && ( (std::fabs(p_x[i]) + shift_) > int_max )){
out = false;
break;
}
}
}
break;
}
default: {
Rf_error("%s cannot handle an object of type %s", __func__, Rf_type2char(TYPEOF(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);
return cpp_all_integerable(x, 0) ? cpp_int64_to_int(x) : cpp_int64_to_double(x);
}

// The reverse operation
Expand Down
Loading

0 comments on commit f2f91a5

Please sign in to comment.