[Rd] Clarifications please.

Simon Urbanek simon.urbanek at r-project.org
Wed Aug 26 22:13:07 CEST 2009


On Aug 26, 2009, at 12:55 , Martin Morgan 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...
>

Actually, lang3 protects all its arguments, so it's safe (and IMHO the  
main point of having this function).

Cheers,
Simon


>>
>>    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
>>
>>
>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>



More information about the R-devel mailing list