Hello,

Since people have whisperred about Rcpp, I'd like to play too.

On 11/15/2010 07:45 AM, Patrick Leyshock wrote:
Very helpful, thank you.

A couple other questions, please:

1.  I've got a function written in C, named "my_c_function".  In my R
code I call this function, passing to it an INTSXP and a STRSXP,
respectively:

   result <- .Call("my_c_function", int_vector, str_vector)

The prototype of "my_c_function" is:

   SEXP my_c_function(SEXP int_vec, SEXP str_vec);

Within my_c_function I am able to extract the values within the integer
vector, e.g. I can grab the first value with these lines of code:

   int extracted_value;
   extracted_value = *INTEGER(int_vec);

What I cannot figure out how to do is extract the value from the
STRSXP.  I'm assuming that I can create a pointer to a character array,
then malloc enough memory to hold the value.  Is there an analogous
operation on "INTEGER" for STRSXPs?

STRING_ELT(str_vec, 0)

gets the 0th component of str_vec, which is a CHARSXP, i.e., an SEXP for
a character string. The char* can be retrieved with CHAR, so the usual
paradigm is

  const char *x = CHAR(STRING_ELT(str_vec, 0));

note the const-ness of the char* -- it's not mutable, because R is
managing char * memory.

The converse action, of assigning to an element, is

  SET_STRING_ELT(str_vec, 0, mkChar("foo"));

mkChar() is creating a copy (if necessary) of "foo", managing it, and
returning a CHARSXP. Working through protection (which will likely be
your next obstacle ;) in this last example is a good exercise.

In Rcpp, you would wrap up the STRSXP into a CharacterVector and then pull things in and out using indexing:

Rcpp::CharacterVector aladdin(str_vec) ;
std::string first = aladdin[0] ;
aladdin[0] = "foobar" ;

There is a parallel operation VECTOR_ELT / SET_VECTOR_ELT for lists.

Same thing for lists:

Rcpp::List yasmine( some_vec_sxp ) ;
double x = yasmine[0] ;
yasmine[0] = "bla" ;

2.  Any good references/resources for developing R?  Nearly all the
documents I've found are for programming R as a user, not as a
developer.  I have copies of the documentation, which are very helpful,
but it'd be helpful to have additional resources to fill in their gaps.

Chambers, 2008, Software for Data Analysis: Programming with R chapters
11 & 12,

Gentleman, 2008, R Programming for Bioinformatics chapter 6

might be helpful, but by the time they arrive you might find that you're
most of the way through the material covered...

I guess my opinion is that Rcpp would not be useful for understanding
R's C layer, whatever its merits for 'getting the job done'.

Right, but we try to put a positive spin on this.

Rcpp hides the C API on purpose, so that users can concentrate on solving their problem rather than deal/fight with the C API.



Back to the original question, Rcpp also has (although it is less used) an Rcpp::S4 class that can be used to deal with slots. Here is a complete example using Rcpp and inline:

require( Rcpp)
require( inline )

setClass("example",
   representation  (
          size = "numeric",
          id    = "character"
   )
)

fx <- cxxfunction( signature(x = "example"),
'
    S4 obj(x) ;
    obj.slot( "size" ) = 10 ;
    obj.slot( "id"   ) = "foo" ;
    return obj ;
', plugin = "Rcpp" )

str( fx( new("example", size=4, id="id_value") ) )

But as Martin says, it all depends on what your goal is: getting the job done or learn about the internal C API.

Romain


Martin


Thank you,

Patrick


On Fri, Nov 12, 2010 at 4:36 PM, Martin Morgan <mtmorgan <at> fhcrc.org
<mailto:mtmorgan <at> fhcrc.org>> wrote:

    On 11/12/2010 02:31 PM, Patrick Leyshock wrote:
    > Hello,
    >
    > I've created this class:
    >
    > setClass("example",
    >    representation  (
    >           size = "numeric",
    >           id    = "character"
    >    )
    > )
    >
    > Suppose I create a new instance of this class:
    >
    >> x <- new("example", 4, "id_value")
    >
    > This creates an S4 object with two slots.  Am I correct in
    thinking that
    > slots are "filled" by SEXPs?

    Hi Patrick --

    If I

    > eg = new("example", size=4, id="id_value")

    (note the named arguments) and take a peak at the str'ucture of eg,
    I see

    > str(eg)
    Formal class 'example' [package ".GlobalEnv"] with 2 slots
     ..@ size: num 4
     ..@ id  : chr "id_value"

    so the @size slot is a numeric vector of length 1 containing the value
    4. One doesn't really have to know the detailed representation, but one
    can find out from

    > .Internal(inspect(eg))
    @df70e48 25 S4SXP g0c0 [OBJ,NAM(2),gp=0x10,ATT]
    ATTRIB:
     @df70ef0 02 LISTSXP g0c0 []
       TAG: @769258 01 SYMSXP g1c0 [MARK] "size"
       @c0f6db8 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 4
       TAG: @15b0228 01 SYMSXP g1c0 [MARK,NAM(2)] "id"
       @c0f6178 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)
         @12341c80 09 CHARSXP g0c2 [gp=0x20] "id_value"
       TAG: @607ce8 01 SYMSXP g1c0 [MARK,NAM(2),gp=0x4000] "class"
       @c0f6d58 16 STRSXP g0c1 [NAM(2),ATT] (len=1, tl=0)
         @96ed08 09 CHARSXP g1c1 [MARK,gp=0x21] "example"
       ATTRIB:
         @df70fd0 02 LISTSXP g0c0 []
           TAG: @624f70 01 SYMSXP g1c0 [MARK,NAM(2)] "package"
           @c0f6d88 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)
             @67f5e0 09 CHARSXP g1c2 [MARK,gp=0x21,ATT] ".GlobalEnv"

    that the 'eg' object is an S4SXP with an attribute that is a LISTSXP.
    The LISTSXP has elements that are tagged with SYMSXP representing the
    slot name, and values that are REALSXP (for 'size') or STRSXP (for
    'id'). The LISTSXP attribute itself has an attribute, which contains
    information about the package where the class is defined. With these
    hints one can see through the S4 interface to the underlying
    implementation

    > attributes(eg)
    $size
    [1] 4

    $id
    [1] "id_value"

    $class
    [1] "example"
    attr(,"package")
    [1] ".GlobalEnv"

    But probably you have a specific goal in mind, and this is too much
    information...

    Martin

    >
    > Thanks, Patrick
    >
    >       [[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


    --
    Computational Biology
    Fred Hutchinson Cancer Research Center
    1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

    Location: M1-B861
    Telephone: 206 667-2793



--
Computational Biology
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109

Location: M1-B861
Telephone: 206 667-2793


--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/9VOd3l : ZAT! 2010
|- http://bit.ly/c6DzuX : Impressionnism with R
`- http://bit.ly/czHPM7 : Rcpp Google tech talk on youtube

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to