[Rd] suggestion of new API function for embedded programming.
EBo
ebo at sandien.com
Thu Sep 4 09:58:03 CEST 2008
I stumbled onto a near trivial solution... here is some example code:
EBo --
#include <Rembedded.h>
#include <Rdefines.h>
#include <Rinternals.h>
#include <R_ext/Parse.h>
SEXP
LineEval (char *cmd)
{
SEXP ans;
int error;
ans = R_tryLineEval (cmd, R_GlobalEnv, &error);
if (error)
{
fprintf (stderr, "Error evaluating line \"%s\"\n", cmd);
return R_NilValue;
}
return ans;
}
SEXP
R_tryLineEval (char *cmd, SEXP rho, int *error)
{
SEXP cmdSexp, cmdexpr, ans = R_NilValue;
int i;
ParseStatus status;
*error = 0;
// parse the R epression
PROTECT(cmdSexp = allocVector(STRSXP, 1));
SET_STRING_ELT(cmdSexp, 0, mkChar(cmd));
cmdexpr = PROTECT(R_ParseVector(cmdSexp, -1, &status, R_NilValue));
if (status != PARSE_OK) {
UNPROTECT(2);
return R_NilValue;
}
// Loop is needed here as EXPSEXP will be of length > 1
for(i = 0; i < length(cmdexpr); i++)
{
ans = R_tryEval(VECTOR_ELT(cmdexpr, i), R_GlobalEnv, error);
if (*error) {
UNPROTECT(2);
return R_NilValue;
}
}
UNPROTECT(2);
return ans;
}
int
main (int argc, char *argv[])
{
char *cmd[] =
{"t.test(x,conf.level=0.67)",
"t.test(x,conf.level=0.67)$conf.int[2]",
"xyz=c(9,8,7,6); xyz=median(x)",
"print(x)",
NULL
};
SEXP ans;
int i;
char *args[] = {"bla", "--gui=none", "--silent", "--no-save"};
Rf_initEmbeddedR (4, args);
// set the variable "x" to the dataset.
SEXP value;
value = NEW_NUMERIC(11);
for (i=10; 0<=i; i--)
NUMERIC_DATA(value)[i] = i;
PROTECT(value);
setVar(install("x"), value, R_GlobalEnv);
// spin through several R expressions and evaluate each.
for (i=0; cmd[i]; i++)
{
ans = LineEval (cmd[i]);
if (R_NilValue != ans)
{
printf ("cmd = \"%s\"\n", cmd[i]);
if (IS_NUMERIC(ans))
printf (" ans is %f\n", REAL(ans)[0]);
else
PrintValue(ans);
printf ("#############\n\n");
}
}
return 0;
}
EBo <ebo at sandien.com> said:
> Luke Tierney <luke at stat.uiowa.edu> said:
>
> > On Wed, 3 Sep 2008, EBo wrote:
> >
> > > Luke Tierney <luke at stat.uiowa.edu> said:
> > >
> > >> ...
> > >>> do something like the following:
> > >>>
> > >>> R_Expr = R_Parse1Buffer(&R_ConsoleIob, 0, &status);
> > >>> if (PARSE_OK==status) {
> > >>> ...
> > >>> value = eval(R_CurrentExpr, rho);
> > >>> ...
> > >>> }
> > >>
> > >> We definitely do NOT want this frozen into the public API.
> > >
> > > What is your objection with making something like this a part of the public
> > > API? I understand that having to use the IOBuffer seems a bit much, but
I do
> > > not understand your concern.
> >
> > We need the freedom to completely change these internals if doing so
> > proves useful.
>
> Ah, that makes perfect sense.
>
> Thanks,
>
> EBo --
>
--
More information about the R-devel
mailing list