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