Hi Simon/Martin I have updated the code. I think I may be doing mistakes with PROTECT and UNPROTECT but the code works fine, no errors or warnings so far. Please suggest any improvements/changes.
#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; const char *x,*y; Rf_initEmbeddedR(argc, argv); // loading fPortfolio library PROTECT(e = lang2(install("library"), mkString("fPortfolio"))); R_tryEval(e, R_GlobalEnv, NULL); UNPROTECT(1); // This is a demo to print out the SWX.RET built-in object // Converting SWX.RET into a matrix PROTECT(e = lang2(install("as.matrix"),install("SWX.RET"))); PROTECT(t1 = (R_tryEval(e, NULL, &errorOccurred))); v=REAL(t1); // Finding the dimensions of the matrix PROTECT(t2=getAttrib(t1,R_DimSymbol)); nx=INTEGER(t2)[0]; ny=INTEGER(t2)[1]; // Obtaining a pointer to the dimnames list of the matrix PROTECT(t2=getAttrib(t1,R_DimNamesSymbol)); // The matrix is stored in column major order so // we print it in this manner. // Printing column headings // This contains the index names of the SWX.RET object for(j=0;j<ny;j++) printf("%s ",(CHAR(STRING_ELT(VECTOR_ELT(t2,1),j)))); printf("\n"); for(i=0;i<nx;i++,j++) { // Printing the rows of the matrix // This contains the date/time values of the SWX.RET object printf("%s ",(CHAR(STRING_ELT(VECTOR_ELT(t2,0),i)))); for(j=0;j<ny;j++) printf("%f ",v[i+(j*ny)]); printf("\n"); } UNPROTECT(3); return 0; } Regards Abhijit Bera On Fri, Aug 28, 2009 at 7:12 PM, Abhijit Bera <abhib...@gmail.com> wrote: > Hi Simon > > Thanks. All the confusion between CHAR and STRING. First I read this : > > http://www1.cuni.cz/~obo/r_surprises.html<http://www1.cuni.cz/%7Eobo/r_surprises.html> > > In the meantime I got your reply. Then I read the documentation and it made > sense! > > Regards > > Abhijit Bera > > > On Fri, Aug 28, 2009 at 6:49 PM, Simon Urbanek < > simon.urba...@r-project.org> wrote: > >> >> 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 <mtmor...@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 <abhib...@gmail.com >>>>> <mailto:abhib...@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 <mtmor...@fhcrc.org >>>>> <mailto:mtmor...@fhcrc.org>> wrote: >>>>> >>>>> Abhijit Bera <abhib...@gmail.com <mailto:abhib...@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@r-project.org <mailto:R-devel@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@r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >>> >>> >>> >> > [[alternative HTML version deleted]] ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel