[Rd] Clarifications please.

Simon Urbanek simon.urbanek at r-project.org
Fri Aug 28 15:19:15 CEST 2009


On Aug 28, 2009, at 7:41 AM, Abhijit Bera wrote:

> Hi Martin
>
> Here's the code. I'm stuck at one point. I cannot figure out how to  
> print
> the dimnames. I've commented it in my code:
>
> int main (int argc, char** argv) {
>
>    SEXP e,t1,t2,val;
>    int errorOccurred,nx,ny,i,j;
>    double *v;
>    char x[1024],y[1024];
>
>    Rf_initEmbeddedR(argc, argv);
>
>    PROTECT(e = lang2(install("library"), mkString("fPortfolio")));
>    R_tryEval(e, R_GlobalEnv, NULL);
>    UNPROTECT(1);
>
>
>    PROTECT(e = lang2(install("as.matrix"),install("SWX.RET")));
>    PROTECT(t1 = (R_tryEval(e, NULL, &errorOccurred)));
>
>    v=REAL(t1);
>
>    PROTECT(t2=getAttrib(t1,R_DimSymbol));
>

FWIW no need to protect it - t1 is already protected and even more so  
you are blowing t2 away two lines later anyway ...


>    nx=INTEGER(t2)[0];
>    ny=INTEGER(t2)[1];
>
>    PROTECT(t2=getAttrib(t1,R_DimNamesSymbol));
>

Again, no need to protect - you have protected t1 already ...


>    // I'm getting stuck here.
>   // I want to print out the dimnames
>   // so that I can get the dates for the timeseries object.
>    strcpy(x,(CHAR(VECTOR_ELT(t2,0))[0]));

Please read docs about character vectors - what you probably meant is  
something like
const char *x = CHAR(STRING_ELT(VECTOR_ELT(t2,0), 0));
printf("dim 1 = (%s, ...)\n", x);

Cheers,
Simon



>    strcpy(y,(CHAR(VECTOR_ELT(t2,1))[0]));
>
>    printf("%d * %d\n  %s %s \n Matrix:\n",nx,ny,x,y);
>
>    // The matrix is stored in column major order so
>    // we print it in this manner.
>    // my previous code was incorrect.
>    for(i=0;i<nx;i++,j++) {
>
>        for(j=0;j<ny;j++)
>         printf("%f ",v[i+(j*ny)]);
>
>        printf("\n");
>
>    }
>
>    //UNPROTECT(3);
>
>    return 0;
>
> }
>
> On Wed, Aug 26, 2009 at 10:25 PM, Martin Morgan <mtmorgan at fhcrc.org>  
> wrote:
>
>> Hi Abhijit --
>>
>> Abhijit Bera wrote:
>>> Hi Martin
>>>
>>> Thanks. I think I got it! Read the R extensions documentation  
>>> again. I
>>> don't even need to convert to a list. This is what I did (just a  
>>> demo):
>>>
>>> #include <R.h>
>>> #include <Rinternals.h>
>>> #include <Rdefines.h>
>>> #include <Rembedded.h>
>>>
>>> int main (int argc, char** argv)  {
>>>
>>>    SEXP e,t1,t2,val;
>>>    int errorOccurred,nx,ny,i,j;
>>>    double *v;
>>>
>>>    Rf_initEmbeddedR(argc, argv);
>>>
>>>    PROTECT(e = lang2(install("library"), mkString("fPortfolio")));
>>>    R_tryEval(e, R_GlobalEnv, NULL);
>>>    UNPROTECT(1);
>>>
>>>    /* We try to evaluate the R expression:
>>>    *  round(cov(100 * SWX.RET), digits = 4)
>>>    *  we shall split it as:
>>>    *  t1<-100*SWX.RET
>>>    *  t2<-cov(t1)
>>>    *  val<-round(t2,4)
>>>    */
>>>
>>>    PROTECT(e = lang3(install("*"),ScalarInteger(100),
>> install("SWX.RET")));
>>>    PROTECT(t1 = (R_tryEval(e, NULL, &errorOccurred)));
>>
>> For what it's worth, and realizing that this is sloppiness in my
>> original code, ScalarInteger(100) (and mkString("fPortfolio"))  
>> returns
>> an unprotected SEXP, so it could in principle be garbage collected  
>> while
>> lang3 is being evaluated...
>>
>>>
>>>    PROTECT(e = lang2(install("cov"),t1));
>>>    PROTECT(t2 = (R_tryEval(e, NULL, &errorOccurred)));
>>>
>>>    PROTECT(e = lang3(install("round"),t2, ScalarInteger(4)));
>>>    PROTECT(val = (R_tryEval(e, NULL, &errorOccurred)));
>>>
>>>    Rf_PrintValue(val);
>>>
>>>   /* This isn't required, is extraneous.
>>>    PROTECT(e = lang2(install("as.list"),val));
>>>    PROTECT(t2 = (R_tryEval(e, NULL, &errorOccurred)));
>>>
>>>    Rf_PrintValue(t2);*/
>>
>> the reason I recommended using as.list (for example) was to respect  
>> the
>> implied abstraction between the object (of class 'timeSeries') and  
>> it's
>> representation. Apparently there is a method as.list.timeSeries,  
>> and a
>> list is something that I am allowed to know about. Your code below
>> works, but doesn't respect the (R-level) abstraction the class author
>> wants. I don't know whether this is regular practice in the R  
>> community,
>> but it seems like the right thing to do.
>>
>> Martin
>>
>>>
>>>    v=REAL(val);
>>>
>>>    PROTECT(t2=getAttrib(val,R_DimSymbol));
>>>
>>>    nx=INTEGER(t2)[0];
>>>    ny=INTEGER(t2)[1];
>>>
>>>    /* Just printing out the matrix
>>>   *  To understand how I can convert
>>>   *  data types b/w R and C
>>>   */
>>>
>>>    printf("Matrix:\n");
>>>
>>>    for(i=0,j=0;i<(nx*ny);i++,j++) {
>>>
>>>        printf("%.4f ",v[i]);
>>>
>>>        if(j==ny-1) {
>>>            printf("\n");
>>>            j=0;
>>>        }
>>>
>>>    }
>>>
>>>    UNPROTECT(6);
>>>
>>>    return 0;
>>>
>>> }
>>>
>>> Regards
>>>
>>> Abhijit Bera
>>>
>>>
>>> On Wed, Aug 26, 2009 at 12:37 PM, Abhijit Bera <abhibera at gmail.com
>>> <mailto:abhibera at gmail.com>> wrote:
>>>
>>>    Hi Martin
>>>
>>>    Thanks. I think I got the hang of it. I will try it out and  
>>> post any
>>>    more queries I have regarding handling data types onto the  
>>> mailing
>> list.
>>>
>>>    Regards
>>>
>>>    Abhijit Bera
>>>
>>>
>>>    On Tue, Aug 25, 2009 at 7:15 PM, Martin Morgan  
>>> <mtmorgan at fhcrc.org
>>>    <mailto:mtmorgan at fhcrc.org>> wrote:
>>>
>>>        Abhijit Bera <abhibera at gmail.com <mailto:abhibera at gmail.com>>
>>>        writes:
>>>
>>>> Hi
>>>>
>>>> I think I have asked these questions earlier, but I been able
>>>        to find
>>>> answers from the documentation (which I found poorly written
>>>        in several
>>>> places). Will someone be kind enough to give me answers and
>>>        enlighten me?
>>>> (as in explain with CODE?)
>>>>
>>>> I want to embed R in my application and use the fPortfolio
>>>        package for
>>>> carrying out risk management computations. Right now I'm
>>>        reading the
>>>> Rmetrics Ebook and trying to convert the various examples into
>>>        embedded C
>>>> code.
>>>>
>>>> Coming from a strictly C background, I have slight difficulty
>> in
>>>> comprehending a functional language like R and it gets worse
>>>        when I try to
>>>> embed R into a procedural language like C. So here is a list
>>>        of my doubts:
>>>>
>>>> 1) I am very confused on how the lang 1 2 3 4 ... set of
>>>        functions work. I
>>>> haven't found any relevant documentation explaining it
>>>        clearly. I have a
>>>> vague idea but still I cannot understand how I would evaluate
>> an R
>>>> expression like Covariance <- round(cov(100 * SWX.RET), digits
>>>        = 4) using
>>>> lang, install and R_tryEval.
>>>
>>>        unroll this as
>>>
>>>         tmp0 <- 100 * SWX.RET
>>>         tmp1 <- cov(tmp0)
>>>         result <- round(tmp2, 4L)
>>>
>>>        so (untested)
>>>
>>>         PROTECT(expr =
>>>           lang3(install("*"), scalarNumeric(100),  
>>> install("SWX.RET")));
>>>         PROTECT(tmp0 = tryEval(expr, R_GlobalEnv, &errorOccurred));
>>>         if (errorOccurred)
>>>           exit(1);
>>>
>>>         PROTECT(expr = lang2(install("cov"), tmp0));
>>>         PROTECT(tmp1 = tryEval(expr, R_GlobalEnv, &errorOccurred));
>>>         if (errorOccurred)
>>>           exit(1);
>>>
>>>         PROTECT(expr = lang3(install("round"), tmp1,  
>>> scalarInteger(4)));
>>>         PROTECT(result = tryEval(expr, R_GlobalEnv,  
>>> &errorOccurred));
>>>         if (errorOccurred)
>>>           exit(1);
>>>
>>>         Rf_PrintValue(result);
>>>         UNPROTECT(6);
>>>
>>>
>>>
>>>> 2) What exactly does install do?
>>>
>>>        creates or locates a symbol in the global symbol table. Every
>> unique
>>>        symbol is recorded and stored in the 'global symbol table'.  
>>> An
>>>        environment is then a mapping between a symbol from this  
>>> table,
>>>        and a
>>>        value unique to the environment. The symbols are being reused
>> across
>>>        environments.
>>>
>>>        In R
>>>
>>>         x <- 10
>>>
>>>        creates a symbol x in the global symbol table, and in the  
>>> global
>>>        environment associates the value 10 with that symbol.
>>>
>>>         env = new.env()
>>>         env$x <- 20
>>>
>>>        uses the same symbol 'x' from the same global symbol table,  
>>> but
>>>        associates the value 20 with it in the environment 'env'.
>>>
>>>        In C
>>>
>>>         install("foo");
>>>
>>>        creates a symbol and returns the appropriate SEXP. And then
>>>
>>>         install("foo")
>>>
>>>        again finds the already-defined symbol and returns the same  
>>> SEXP.
>>>
>>>> 3) I wrote the following code:
>>>>
>>>> #include <Rinternals.h>
>>>> #include <Rembedded.h>
>>>>
>>>> int main (int argc, char** argv) {
>>>>
>>>>    SEXP e,val;
>>>>    int errorOccurred;
>>>>
>>>>    Rf_initEmbeddedR(argc, argv);
>>>>
>>>>    // library("fPortfolio")
>>>>    PROTECT(e = lang2(install("library"),
>>>        mkString("fPortfolio")));
>>>>    R_tryEval(e, R_GlobalEnv, NULL);
>>>>    UNPROTECT(1);
>>>>
>>>>   // colMeans(SWX.RET)
>>>>    PROTECT(e = lang2(install("colMeans"),
>> install("SWX.RET")));
>>>>    val = (R_tryEval(e, NULL, &errorOccurred));
>>>>
>>>>    Rf_PrintValue(val);
>>>>
>>>>    return 0;
>>>>
>>>> }
>>>>
>>>> When I tried :
>>>>
>>>>> mean(SWX.RET)
>>>>
>>>> in the R prompt I got the following output:
>>>>
>>>>         SBI          SPI          SII         LP25
>> LP40
>>>> LP60
>>>> 4.660521e-06 2.153198e-04 2.033869e-04 1.388886e-04
>> 1.349041e-04
>>>> 1.226859e-04
>>>>
>>>>
>>>> However when I replaced colMeans with mean in the C code above
>>>        I got a mean
>>>> of the means (0.0001366410) of all the columns when
>>>        Rf_PrintValue was
>>>> called. Using colMeans gave me the output as shown above. Why
>>>        does this
>>>> happen? How do I get the above output using mean?
>>>
>>>        Guessing a little; I don't know what class SWX.RET is, but
>> perhaps
>>>        there is a method mean.class_of_SWX.RET defined in a  
>>> package that
>> is
>>>        loaded in your R session, but not your C session. In a new  
>>> R I
>> see
>>>
>>>> library(fPortfolio)
>>>> mean(SWX.RET)
>>>        [1] 0.0001366410
>>>
>>>> 4) From the above code segment, how can I deal with the
>>>        SEXPREC val which is
>>>> returned by R_tryEval in the above code and convert it to my
>>>        own local
>>>> vector datatype? How do I access the values of val? val will
>>>        now be a
>>>> timeseries so how do i convert it?
>>>
>>>        Convert it to a 'standard' R object using appropriate R
>>>        functions and
>>>        access it using C, e.g.,
>>>
>>>> lst <- as.list(SWX.RET)
>>>> str(lst)
>>>        List of 6
>>>        $ SBI : num [1:1916] -0.002088 -0.000105 -0.00136 0.000419  
>>> 0 ...
>>>        $ SPI : num [1:1916] -0.03439 -0.01041 0.01212 0.02246  
>>> 0.00211
>> ...
>>>        $ SII : num [1:1916] 1.37e-05 -4.96e-03 3.81e-03 -6.16e-04
>>>        2.38e-03 ...
>>>        $ LP25: num [1:1916] -0.01199 -0.00366 -0.00132 0.00771  
>>> 0.00303
>> ...
>>>        $ LP40: num [1:1916] -0.01801 -0.00584 -0.00164 0.01166  
>>> 0.00457
>> ...
>>>        $ LP60: num [1:1916] -0.02616 -0.00901 -0.0024 0.01706  
>>> 0.00695
>> ...
>>>
>>>        so in C, once I have lst, I could
>>>
>>>         sbi = VECTOR_ELT(lst, 0);
>>>         double *vals = NUMERIC(sbi);
>>>         printf("%f", vals[0]); # -002088
>>>
>>>        Hope that helps, and is not too misleading, I didn't have  
>>> time to
>>>        check carefully.
>>>
>>>        Martin
>>>
>>>> Thanks
>>>>
>>>> Abhijit Bera
>>>>
>>>>      [[alternative HTML version deleted]]
>>>>
>>>> ______________________________________________
>>>> R-devel at r-project.org <mailto:R-devel at r-project.org> mailing
>> list
>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>>        --
>>>        Martin Morgan
>>>        Computational Biology / Fred Hutchinson Cancer Research  
>>> Center
>>>        1100 Fairview Ave. N.
>>>        PO Box 19024 Seattle, WA 98109
>>>
>>>        Location: Arnold Building M1 B861
>>>        Phone: (206) 667-2793
>>>
>>>
>>>
>>
>>
>
> 	[[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>



More information about the R-devel mailing list