Skip to content

Commit 03f2b6c

Browse files
committed
few changes
1 parent 5ffbe2e commit 03f2b6c

File tree

9 files changed

+225
-17
lines changed

9 files changed

+225
-17
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: kit
22
Type: Package
33
Title: Data Manipulation Functions Implemented in C
4-
Version: 0.0.10
5-
Date: 2021-11-28
4+
Version: 0.0.11
5+
Date: 2022-03-19
66
Authors@R: c(person("Morgan", "Jacob", role = c("aut", "cre", "cph"), email = "[email protected]"))
77
Author: Morgan Jacob [aut, cre, cph]
88
Maintainer: Morgan Jacob <[email protected]>

MD5

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
6071edd604dbeb75308cfbedc7790398 *cleanup
22
66d4daddd0163539f19e2cb783fc3bb9 *configure
3-
605e6204374516c0de6e469b20fe6e94 *DESCRIPTION
4-
076ff1db625e3c31447a692ff9fbd665 *inst/NEWS.Rd
3+
8f0d23884ad1cce08b347b8ffb408fc6 *DESCRIPTION
4+
90a9d0d38d3c9bcd9ce3a481c11e68d1 *inst/NEWS.Rd
55
a87b0f223435ed35607e8514562b8bfe *LICENSE
66
6375b9e30533e0495b98f4b5b829706b *man/charToFact.Rd
77
8f19a2c9feb2f352580fd4892650f285 *man/count.Rd
@@ -16,22 +16,22 @@ a137f7855b41b074e2babaf8a1562551 *man/shareData.Rd
1616
54f91d543a10f8c9aef7082da2b86de7 *man/topn.Rd
1717
3c628c2a27764ec5df2b4980921c310f *man/vswitch.Rd
1818
640100c58f36cf06c14aacd7ff7a946a *NAMESPACE
19-
7d7d1d54ca3f9f17e4141de6c2b1ce34 *R/call.R
19+
4ee9cafbcfe244008724abc4a9be9d77 *R/call.R
2020
34ba4d931a5bd0ba120ddef7e5327313 *README.md
2121
4826023c3ffe528db5e2af5db2a84b5a *src/dup.c
2222
e86a1960c335e7d534a4683b52d8b70c *src/dupLen.c
2323
84dc17b4330566e5beb69626ad9d268e *src/fpos.c
2424
c362509861cd6835c1d8adbb0dce02b4 *src/iif.c
25-
253a8c2c729dc6e0557dd70cf6e7f530 *src/init.c
26-
4f0b51d262c28db77550bca462b21ffa *src/kit.h
25+
d4bb3a264eeb1057c8a6063395518adb *src/init.c
26+
e863c7a65694fd614f9fb33b0cc9ca25 *src/kit.h
2727
a52426250b954a335b1121948e057ee7 *src/Makevars.in
2828
95e3011e37d9dde0d75f3a3819b2acd3 *src/Makevars.win
2929
8e997b5d5d44af5cea7eafb48a4b9745 *src/nswitch.c
3030
ab9528d1b24d71ed2080743331b8a012 *src/psort.c
31-
44018b12fca6cccaabcd0f10deb421e4 *src/psum.c
31+
e4e5b46734dfaa690cf9f8889a415a8d *src/psum.c
3232
bafdafd654269acd054525571dbe1b44 *src/share.c
3333
53711690f6c15f3f36edb4b9360043a4 *src/topn.c
3434
c0f3fe6fca4e8492277a0d5f87528ce5 *src/utils.c
3535
3476a1e2381bb86f68a72844ee61bc7b *src/vswitch.c
36-
336bd08ef00d953278cf64a00a000ac9 *tests/test_kit.R
37-
f871740ade1b3172748d7b1f63586098 *tests/test_kit.Rout.save
36+
0b70b926bee3387b548fc0ac0ee48b30 *tests/test_kit.R
37+
a9113c4b07bf0ce9653b5143d1f159af *tests/test_kit.Rout.save

R/call.R

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ nif = function(..., default=NULL) .Call(CnifR, default, parent.frame(),
1111
nswitch = function(x, ..., default=NULL, nThread=getOption("kit.nThread"), checkEnc = TRUE) .Call(CnswitchR, x, default, nThread, checkEnc, list(...))
1212
pall = function(..., na.rm=FALSE) .Call(CpallR, na.rm, if (...length() == 1L && is.list(..1)) ..1 else list(...))
1313
pany = function(..., na.rm=FALSE) .Call(CpanyR, na.rm, if (...length() == 1L && is.list(..1)) ..1 else list(...))
14-
pcount = function(..., value) .Call(CpcountR, value, list(...))
1514
pmean = function(..., na.rm=FALSE) .Call(CpmeanR, na.rm, if (...length() == 1L && is.list(..1)) ..1 else list(...))
1615
pprod = function(..., na.rm=FALSE) .Call(CpprodR, na.rm, if (...length() == 1L && is.list(..1)) ..1 else list(...))
1716
psum = function(..., na.rm=FALSE) .Call(CpsumR, na.rm, if (...length() == 1L && is.list(..1)) ..1 else list(...))
@@ -20,10 +19,18 @@ topn = function(vec, n=6L, decreasing=TRUE, hasna=TRUE,index=TRUE) if(ind
2019
uniqLen = function(x) .Call(CdupLenR, x)
2120
vswitch = function(x, values, outputs, default=NULL, nThread=getOption("kit.nThread"), checkEnc = TRUE) .Call(CvswitchR, x, values, outputs, default, nThread, checkEnc)
2221

23-
.onAttach = function(libname, pkgname) packageStartupMessage(paste0("Attaching kit 0.0.10 (OPENMP ",if(.Call(CompEnabledR)) "enabled" else "disabled"," using 1 thread)"))
22+
.onAttach = function(libname, pkgname) packageStartupMessage(paste0("Attaching kit 0.0.11 (OPENMP ",if(.Call(CompEnabledR)) "enabled" else "disabled"," using 1 thread)"))
2423
.onLoad = function(libname, pkgname) options("kit.nThread"=1L) #nocov
2524
.onUnload = function(libpath) library.dynam.unload("kit", libpath) #nocov
2625

26+
pcount = function(..., value) {
27+
if(is.na(value[1])) {
28+
.Call(CpcountNAR, value, if (...length() == 1L && is.list(..1)) ..1 else list(...))
29+
} else {
30+
.Call(CpcountR, value, if (...length() == 1L && is.list(..1)) ..1 else list(...))
31+
}
32+
}
33+
2734
psort = function(x, decreasing = FALSE, na.last = NA, nThread=getOption("kit.nThread"), c.locale = TRUE) {
2835
if (typeof(x) == "character") {
2936
return(.Call(CcpsortR, x, decreasing, nThread, na.last,parent.frame(), FALSE, c.locale))

inst/NEWS.Rd

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@
44

55
\newcommand{\CRANpkg}{\href{https://CRAN.R-project.org/package=#1}{\pkg{#1}}}
66

7+
\section{version 0.0.11 (2022-03-19)}{
8+
\subsection{New Features}{
9+
\itemize{
10+
\item Function \code{\strong{pcount}} now supports data.frame.
11+
}
12+
}
13+
\subsection{Bug Fixes}{
14+
\itemize{
15+
\item Function \code{\strong{pcount}} now works with specific NA values, i.e. NA_real_, NA_character_ etc...
16+
}
17+
}
18+
}
19+
720
\section{version 0.0.10 (2021-11-28)}{
821
\subsection{New Features}{
922
\itemize{

src/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ static const R_CallMethodDef CallEntries[] = {
1616
{"CpanyR", (DL_FUNC) &panyR, -1},
1717
{"CpallR", (DL_FUNC) &pallR, -1},
1818
{"CpcountR", (DL_FUNC) &pcountR, -1},
19+
{"CpcountNAR", (DL_FUNC) &pcountNAR, -1},
1920
{"CpmeanR", (DL_FUNC) &pmeanR, -1},
2021
{"CpprodR", (DL_FUNC) &pprodR, -1},
2122
{"CpsumR", (DL_FUNC) &psumR, -1},
@@ -45,6 +46,7 @@ void R_init_kit(DllInfo *dll) {
4546
R_RegisterCCallable("kit", "CpanyR", (DL_FUNC) &panyR);
4647
R_RegisterCCallable("kit", "CpallR", (DL_FUNC) &pallR);
4748
R_RegisterCCallable("kit", "CpcountR", (DL_FUNC) &pcountR);
49+
R_RegisterCCallable("kit", "CpcountNAR", (DL_FUNC) &pcountNAR);
4850
R_RegisterCCallable("kit", "CpmeanR", (DL_FUNC) &pmeanR);
4951
R_RegisterCCallable("kit", "CpprodR", (DL_FUNC) &pprodR);
5052
R_RegisterCCallable("kit", "CpsumR", (DL_FUNC) &psumR);

src/kit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ extern SEXP ompEnabledR();
9393
extern SEXP pallR(SEXP na, SEXP args);
9494
extern SEXP panyR(SEXP na, SEXP args);
9595
extern SEXP pcountR(SEXP x, SEXP args);
96+
extern SEXP pcountNAR(SEXP x, SEXP args);
9697
extern SEXP pmeanR(SEXP na, SEXP args);
9798
extern SEXP pprodR(SEXP na, SEXP args);
9899
extern SEXP psumR(SEXP na, SEXP args);

src/psum.c

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,3 +678,188 @@ SEXP pcountR(SEXP x, SEXP args) {
678678
UNPROTECT(1);
679679
return ans;
680680
}
681+
682+
SEXP pcountNAR(SEXP x, SEXP args) {
683+
if (xlength(x) != 1 || isNull(x)) {
684+
error("Argument 'value' must be non NULL and length 1.");
685+
}
686+
const int n=length(args);
687+
if (n < 1) {
688+
error("Please supply at least 1 argument. (%d argument supplied)", n);
689+
}
690+
const SEXP args0 = PTR_ETL(args, 0);
691+
SEXPTYPE anstype = UTYPEOF(args0);
692+
const R_xlen_t len0 = xlength(args0);
693+
if (anstype != LGLSXP && anstype != INTSXP && anstype != REALSXP &&
694+
anstype != CPLXSXP && anstype != STRSXP) {
695+
error("Argument %d is of type %s. Only logical, integer, double, complex and"
696+
" character types are supported.", 1, type2char(anstype));
697+
}
698+
SEXPTYPE tx = UTYPEOF(x);
699+
if (anstype != tx) {
700+
error("Type of 'value' (%s) is different than type of Argument %d (%s). "
701+
"Please make sure both have the same type.", type2char(tx), 1, type2char(anstype));
702+
}
703+
SEXP classx = PROTECT(getAttrib(x, R_ClassSymbol));
704+
if(!R_compute_identical(PROTECT(getAttrib(args0, R_ClassSymbol)), classx, 0)) {
705+
error("Class of 'value' is different than class of Argument %d. "
706+
"Please make sure both have the same class.", 1);
707+
}
708+
UNPROTECT(1);
709+
int nprotect = 0;
710+
const bool xf = isFactor(x);
711+
SEXP levelsx;
712+
if (xf) {
713+
levelsx = PROTECT(getAttrib(x, R_LevelsSymbol)); nprotect++;
714+
if (!R_compute_identical(levelsx, PROTECT(getAttrib(args0, R_LevelsSymbol)), 0)) {
715+
error("Levels of 'value' are different than levels of Argument %d. "
716+
"Please make sure both have the same levels.", 1);
717+
}
718+
UNPROTECT(1);
719+
}
720+
for (int i = 1; i < n; ++i) {
721+
SEXPTYPE type = UTYPEOF(PTR_ETL(args, i));
722+
R_xlen_t len1 = xlength(PTR_ETL(args, i));
723+
if (type != anstype) {
724+
error("Type of argument %d is %s but argument %d is of type %s. "
725+
"Please make sure both have the same type.", i+1,
726+
type2char(type), 1, type2char(anstype));
727+
}
728+
if(!R_compute_identical(PROTECT(getAttrib(PTR_ETL(args, i), R_ClassSymbol)), classx, 0)) {
729+
error("Class of 'value' is different than class of Argument %d. "
730+
"Please make sure both have the same class.", i+1);
731+
}
732+
UNPROTECT(1);
733+
if (xf) {
734+
if (!R_compute_identical(levelsx, PROTECT(getAttrib(PTR_ETL(args, i), R_LevelsSymbol)), 0)) {
735+
error("Levels of 'value' are different than levels of Argument %d. "
736+
"Please make sure both have the same levels.", i + 1);
737+
}
738+
UNPROTECT(1);
739+
}
740+
if (len1 != len0) {
741+
error("Argument %d is of length %zu but argument %d is of length %zu. "
742+
"If you wish to 'recycle' your argument, please use rep() to make this intent "
743+
"clear to the readers of your code.", i+1, len1, 1, len0);
744+
}
745+
}
746+
UNPROTECT(1 + nprotect);
747+
SEXP ans;
748+
if (len0 > INT_MAX) {
749+
ans = PROTECT(allocVector(REALSXP, len0)); // # nocov start
750+
double *restrict pans = REAL(ans);
751+
memset(pans, 0, (unsigned)len0*sizeof(double));
752+
switch(anstype) {
753+
case LGLSXP: {
754+
for (int i = 0; i < n; ++i) {
755+
int *pa = LOGICAL(PTR_ETL(args, i));
756+
for (ssize_t j = 0; j < len0; ++j) {
757+
if (pa[j] == NA_LOGICAL) {
758+
pans[j]++;
759+
}
760+
}
761+
}
762+
} break;
763+
case INTSXP: {
764+
for (int i = 0; i < n; ++i) {
765+
int *pa = INTEGER(PTR_ETL(args, i));
766+
for (ssize_t j = 0; j < len0; ++j) {
767+
if (pa[j] == NA_INTEGER) {
768+
pans[j]++;
769+
}
770+
}
771+
}
772+
} break;
773+
case REALSXP: {
774+
for (int i = 0; i < n; ++i) {
775+
double *pa = REAL(PTR_ETL(args, i));
776+
for (ssize_t j = 0; j < len0; ++j) {
777+
if (ISNAN(pa[j])) {
778+
pans[j]++;
779+
}
780+
}
781+
}
782+
} break;
783+
case CPLXSXP: {
784+
for (int i = 0; i < n; ++i) {
785+
Rcomplex *pa = COMPLEX(PTR_ETL(args, i));
786+
for (ssize_t j = 0; j < len0; ++j) {
787+
if (ISNAN_COMPLEX(pa[j])) {
788+
pans[j]++;
789+
}
790+
}
791+
}
792+
} break;
793+
case STRSXP: {
794+
for (int i = 0; i < n; ++i) {
795+
const SEXP pa = PTR_ETL(args, i);
796+
const SEXP *restrict px = STRING_PTR(pa);
797+
for (ssize_t j = 0; j < len0; ++j) {
798+
if (px[j] == NA_STRING) {
799+
pans[j]++;
800+
}
801+
}
802+
}
803+
} break;
804+
} // # nocov end
805+
} else {
806+
ans = PROTECT(allocVector(INTSXP, len0));
807+
int *restrict pans = INTEGER(ans);
808+
memset(pans, 0, (unsigned)len0*sizeof(int));
809+
switch(anstype) {
810+
case LGLSXP: {
811+
for (int i = 0; i < n; ++i) {
812+
int *pa = LOGICAL(PTR_ETL(args, i));
813+
for (ssize_t j = 0; j < len0; ++j) {
814+
if (pa[j] == NA_LOGICAL) {
815+
pans[j]++;
816+
}
817+
}
818+
}
819+
} break;
820+
case INTSXP: {
821+
for (int i = 0; i < n; ++i) {
822+
int *pa = INTEGER(PTR_ETL(args, i));
823+
for (ssize_t j = 0; j < len0; ++j) {
824+
if (pa[j] == NA_INTEGER) {
825+
pans[j]++;
826+
}
827+
}
828+
}
829+
} break;
830+
case REALSXP: {
831+
for (int i = 0; i < n; ++i) {
832+
double *pa = REAL(PTR_ETL(args, i));
833+
for (ssize_t j = 0; j < len0; ++j) {
834+
if (ISNAN(pa[j])) {
835+
pans[j]++;
836+
}
837+
}
838+
}
839+
} break;
840+
case CPLXSXP: {
841+
for (int i = 0; i < n; ++i) {
842+
Rcomplex *pa = COMPLEX(PTR_ETL(args, i));
843+
for (ssize_t j = 0; j < len0; ++j) {
844+
if (ISNAN_COMPLEX(pa[j])) {
845+
pans[j]++;
846+
}
847+
}
848+
}
849+
} break;
850+
case STRSXP: {
851+
for (int i = 0; i < n; ++i) {
852+
const SEXP pa = PTR_ETL(args, i);
853+
const SEXP *restrict px = STRING_PTR(pa);
854+
for (ssize_t j = 0; j < len0; ++j) {
855+
if (px[j] == NA_STRING) {
856+
pans[j]++;
857+
}
858+
}
859+
}
860+
} break;
861+
}
862+
}
863+
UNPROTECT(1);
864+
return ans;
865+
}

tests/test_kit.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,8 +1184,8 @@ check("0014.002", pcount(as.integer(x), value = 3L), sapply(1:4, function(i) cou
11841184
check("0014.003", pcount(as.character(x), value = "3"), sapply(1:4, function(i) count(as.character(x[i]), "3")))
11851185
check("0014.004", pcount(as.complex(x), value = 3+0i), sapply(1:4, function(i) count(as.complex(x[i]), 3+0i)))
11861186
check("0014.005", pcount(as.logical(x), value = TRUE), sapply(1:4, function(i) count(as.logical(x[i]), TRUE)))
1187-
check("0014.006", pcount(as.logical(x), value = NULL), error = "Argument 'value' must be non NULL and length 1.")
1188-
check("0014.007", pcount(as.logical(x), value = c(TRUE,FALSE)), error = "Argument 'value' must be non NULL and length 1.")
1187+
check("0014.006", pcount(as.logical(x), value = NULL), error = "argument is of length zero")
1188+
check("0014.007", pcount(x, value = NA_real_), c(0L,0L,1L,0L))
11891189
check("0014.008", pcount(value = TRUE), error = "Please supply at least 1 argument. (0 argument supplied)")
11901190
check("0014.009", pcount(x,y,z,value = 3), c(1L,1L,0L,0L))
11911191
check("0014.010", pcount(x,y,z,value = 4), c(0L,1L,2L,0L))

tests/test_kit.Rout.save

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Type 'q()' to quit R.
5353
+ }
5454
>
5555
> library(kit); unloadNamespace("kit")
56-
Attaching kit 0.0.10 (OPENMP enabled using 1 thread)
56+
Attaching kit 0.0.11 (OPENMP enabled using 1 thread)
5757
>
5858
> topn = kit::topn
5959
> setlevels = kit::setlevels
@@ -1204,8 +1204,8 @@ Attaching kit 0.0.10 (OPENMP enabled using 1 thread)
12041204
> check("0014.003", pcount(as.character(x), value = "3"), sapply(1:4, function(i) count(as.character(x[i]), "3")))
12051205
> check("0014.004", pcount(as.complex(x), value = 3+0i), sapply(1:4, function(i) count(as.complex(x[i]), 3+0i)))
12061206
> check("0014.005", pcount(as.logical(x), value = TRUE), sapply(1:4, function(i) count(as.logical(x[i]), TRUE)))
1207-
> check("0014.006", pcount(as.logical(x), value = NULL), error = "Argument 'value' must be non NULL and length 1.")
1208-
> check("0014.007", pcount(as.logical(x), value = c(TRUE,FALSE)), error = "Argument 'value' must be non NULL and length 1.")
1207+
> check("0014.006", pcount(as.logical(x), value = NULL), error = "argument is of length zero")
1208+
> check("0014.007", pcount(x, value = NA_real_), c(0L,0L,1L,0L))
12091209
> check("0014.008", pcount(value = TRUE), error = "Please supply at least 1 argument. (0 argument supplied)")
12101210
> check("0014.009", pcount(x,y,z,value = 3), c(1L,1L,0L,0L))
12111211
> check("0014.010", pcount(x,y,z,value = 4), c(0L,1L,2L,0L))

0 commit comments

Comments
 (0)