Skip to content

Commit

Permalink
create the sparse vectors inside C
Browse files Browse the repository at this point in the history
  • Loading branch information
EmilHvitfeldt committed Oct 17, 2024
1 parent 04724a1 commit 769562a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 7 deletions.
8 changes: 1 addition & 7 deletions R/sparse_dummy.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,8 @@ sparse_dummy <- function(x, lvls = NULL) {
x <- as.integer(x)

counts <- tabulate(x)


res <- .Call(ffi_sparse_dummy, x, lvls, counts)
names(res) <- lvls

lapply(res, create_dummy, length(x))
}

create_dummy <- function(x, len) {
new_sparse_integer(rep(1L, length(x)), x, len, 0L)
res
}
32 changes: 32 additions & 0 deletions src/sparse-dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@
extern SEXP ffi_altrep_new_sparse_integer(SEXP);
extern void sparsevctrs_init_altrep_sparse_integer(DllInfo*);

SEXP create_dummy(SEXP pos, R_xlen_t length) {
SEXP out = PROTECT(Rf_allocVector(VECSXP, 4));

R_xlen_t pos_len = Rf_length(pos);

SEXP out_val = Rf_allocVector(INTSXP, pos_len);
SET_VECTOR_ELT(out, 0, out_val);
int* v_out_val = INTEGER(out_val);

for (R_xlen_t i = 0; i < pos_len; ++i) {
v_out_val[i] = 1;
}

SET_VECTOR_ELT(out, 1, pos);

SEXP out_length = Rf_ScalarInteger((int) length);
SET_VECTOR_ELT(out, 2, out_length);

SEXP out_default = Rf_ScalarInteger(0);
SET_VECTOR_ELT(out, 3, out_default);

UNPROTECT(1);

return ffi_altrep_new_sparse_integer(out);
}

SEXP ffi_sparse_dummy(SEXP x, SEXP lvls, SEXP counts) {
R_xlen_t n_lvls = Rf_length(lvls);
R_xlen_t x_length = Rf_length(x);
Expand All @@ -29,6 +55,12 @@ SEXP ffi_sparse_dummy(SEXP x, SEXP lvls, SEXP counts) {
v_pos_index[current_val - 1]++;
}

for (R_xlen_t i = 0; i < n_lvls; ++i) {
SEXP pos = VECTOR_ELT(out, i);
SEXP dummy = create_dummy(pos, x_length);
SET_VECTOR_ELT(out, i, dummy);
}

UNPROTECT(2);

return out;
Expand Down

0 comments on commit 769562a

Please sign in to comment.