[Rd] C function with unknown output length
Dirk Eddelbuettel
edd at debian.org
Wed Jun 6 20:19:58 CEST 2007
Salut Vincent,
On 6 June 2007 at 13:17, Vincent Goulet wrote:
| Could anyone point me to one or more examples in the R sources of a C
| function that is called without knowing in advance what will be the
| length (say) of the output vector?
|
| To make myself clearer, we have a C function that computes
| probabilities until their sum gets "close enough" to 1. Hence, the
| number of probabilities is not known in advance.
|
| I would like to have an idea what is the best way to handle this
| situation in R.
I haven't been on the 'Dirk tells everybody to use RcppTemplate' soapbox
lately, so let me (drumroll) suggest to use RcppTemplate.
So if you were to consider C++, which can be done incrementally relative to
C, then you could collect your data in a self-growing, autonagically
managemed STL Vector, pass it to RcppTemplate, and you're done. I have a
local .deb package for r-cran-rcpptemplate I can send you (and which I should
upload to Debian), or you can just use it from source on CRAN. You want the
source for the examples anyway.
If C++ is not an option, then I typically just hunt for decent examples that
do similar stuff. BDR's RODBC is usually a good source -- he also does not
know ex ante how long the return sets are. It's not _that_ hard, just
tedious. You examine the length of your vector, assign a new one for results
of that length, and copy elements.
As an example, see the following from my rdieharder package (that is pending
an upload to CRAN) where C as opposed to C++ was a given constraint. I wrote
this in a hurry and I may well have missed something to make it a tad better
-- but as indicated above, I'd rather be doing it in C++ anyway.
In the code, element [1] is a vector of possibly varying size:
/* vector of size three: [0] is scalar ks_pv, [1] is pvalues vec, [2] name */
PROTECT(result = allocVector(VECSXP, 3));
/* alloc scalar, and set it */
PROTECT(pv = allocVector(REALSXP, 1));
REAL(pv)[0] = testptr->ks_pvalue;
/* vector and set it */
PROTECT(vec = allocVector(REALSXP, testptr->psamples));
for (i = 0; i < testptr->psamples; i++) {
REAL(vec)[i] = testptr->pvalues[i];
}
PROTECT(name = allocVector(STRSXP, 1));
SET_STRING_ELT(name, 0, mkChar(dtestptr->name));
/* insert scalar and vector */
SET_VECTOR_ELT(result, 0, pv);
SET_VECTOR_ELT(result, 1, vec);
SET_VECTOR_ELT(result, 2, name);
UNPROTECT(4);
return result;
and testptr->psamples has the unknonw 'N' of vector length.
And yes, we need better cookbook examples for all this.
Hth, Dirk
--
Hell, there are no rules here - we're trying to accomplish something.
-- Thomas A. Edison
More information about the R-devel
mailing list