Skip to content

R-devel Digest, Vol 109, Issue 22

12 messages · Peter Dalgaard, Ramon Diaz-Uriarte, Simon Urbanek +2 more

#
On Thu, 22 Mar 2012 10:38:55 -0400,Simon Urbanek <simon.urbanek at r-project.org> wrote:

            
After your previous email I made a mental note "try to finally learn to
use .Call since I often deal with large objects". So, yes, I'd love to see
a ref card and cheat sheet: I have tried learning to use .Call a few
times, but have always gone back to .C since (it seems that) all I needed
to know are just a couple of conventions, and the rest is "C as usual".



You say "if I find out what people find challenging on
.Call". Hummm... can I answer "basically everything"?  I think Terry
Thereneau says, "the things I needed to know are scattered about in
multiple places". When I see the convolve example (5.2 in Writing R
extensions) I understand the C code; when I see the convolve2 example in
5.10.1 I think I can guess what lines "PROTECT(a ..." to "xab =
NUMERIC_POINTER ..."  might be doing, but I would not know how to do that
on my own. Yes, I can go to 5.9.1 to read about PROTECT, then search for
... But, at that point, I've gone back to .C. Of course, this might just
be my laziness/incompetence/whatever.

 

Best,


R.

        
#
Don't know how useful it is any more, but back in the days, I gave this talk in Vienna

http://www.ci.tuwien.ac.at/Conferences/useR-2004/Keynotes/Dalgaard.pdf

Looking at it now, perhaps it moves a little too quickly into the hairy stuff. On the other hand, those were the things that I had found important to figure out at the time. At a quick glance, I didn't spot anything obviously outdated.
On Mar 22, 2012, at 16:15 , Ramon Diaz-Uriarte wrote:

            

  
    
#
On 03/22/2012 11:03 AM, peter dalgaard wrote:
Peter,
   I just looked at this, and I'd say that moved into the hairy stuff 
way too quickly.  Much of what it covered I would never expect to use.  
Some I ddn't understand.  Part of this of course is that slides for a 
talk are rarely very useful without the talker.

  Something simpler for the layman would be good.

Terry T.
#
Peter, thanks for the slides. However, I felt like Terry and I think
because I am missing the "big picture" that I was somewhat surprised by
some of the content and organization (e.g., the detail about character
vectors, the usage of the tcltk package as example code).

Best,

R.
On Thu, 22 Mar 2012 12:45:14 -0500,Terry Therneau <therneau at mayo.edu> wrote:

  
    
#
This is my shot at a cheat sheet.
comments are welcome.

Simon

-------------- next part --------------
A non-text attachment was scrubbed...
Name: R API cheat sheet.pdf
Type: application/pdf
Size: 51661 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20120323/a13f948a/attachment.pdf>
-------------- next part --------------
On Mar 23, 2012, at 6:35 AM, Ramon Diaz-Uriarte wrote:

            
#
Awesome. I love the reference card. This will be useful.

But I couldn't resist recasting your final "silly" example into 

  a) inline use which I find generally easier than having to do R CMD SHLIB
     followed by dyn.load() 

  b) a comparison with Rcpp which looks just about the same minus some
     UPPERCASE terms stemming from the R API.  

     We turn error() into Rf_error() as that is a toggle Rcpp sets (given how
     error(), length(), etc conflict at times with things of the same name
     coming from somewhere else). Alternatively, we could also use 'throw
     std::range_error("invalid n")' which then calls Rf_error for us.

     It uses one templated cast to int, but the intent is as readable as
     asInteger. You could of course use asInteger too, as Doug eg prefers.

     It then declares on list type of the right size. Alloc and all that is
     done behind the scenes -- abstraction.  And the assignment of the
     unaltered SEXP type x that is prelicated may just be simpler. 

Code is below for both variants, and the same outputs.

Dirk

R> library(inline)
R> 
R> replicateToListC <- cfunction(signature(x="any", N="integer"), body='
+    int n = asInteger(N);
+    if (n < 0) error("N must be non-negative");
+    SEXP res = allocVector(VECSXP, n);
+    for (int i = 0; i < n; i++) SET_VECTOR_ELT(res, i, x);
+    return res;
+ ')
R> 
R> replicateToListC(1:2, -2)
Error in replicateToListC(1:2, -2) : N must be non-negative
R> replicateToListC(1:2, 2)
[[1]]
[1] 1 2

[[2]]
[1] 1 2

R> 
R> replicateToListCpp <- cxxfunction(signature(x="any", N="integer"), plugin="Rcpp", body='
+    int n = as<int>(N);
+    if (n < 0) Rf_error("N must be non-negative");
+    List res(n);
+    for (int i = 0; i < n; i++) res[i] = x;
+    return res;
+ ')
R> 
R> replicateToListCpp(1:2, -2)
Error in replicateToListCpp(1:2, -2) : N must be non-negative
R> replicateToListCpp(1:2, 2)
[[1]]
[1] 1 2

[[2]]
[1] 1 2

R> 
R>
3 days later
#
On 03/23/2012 10:58 AM, Simon Urbanek wrote:
I was looking through the cheat sheet.  It's nice.  There are a few 
things in it that I can't find in the documentation though.  Where would 
one find a description?  (I can guess, but that may be dangerous).

mkNamed
R_Naint   (I don't see quite how this differs from using NA_INTEGER to 
set a result)
R_PreserveObject, R_ReleaseObject   (Advantages/disadvantages wrt PRESERVE?)

The last is the most interesting to me.

Terry T.



-------------- next part --------------
A non-text attachment was scrubbed...
Name: R API cheat sheet.pdf
Type: application/pdf
Size: 51660 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20120327/2098440a/attachment.pdf>
#
On Mar 27, 2012, at 12:03 PM, Terry Therneau wrote:

            
It is a shorthand for using allocVector and then setting names (which can be tedious). It's a simple way to create a result list/object (a very common thing to do):

    SEXP res = PROTECT(mkNamed(VECSXP, (const char*[]) { "foo", "bar", ""}));
    // fill res with SET_VECTOR_ELT(res, ..) 
    setAttrib(res, R_ClassSymbol, mkString("myClass"));
    UNPROTECT(1);
    return res;

Note that the sentinel is "" (not not NULL as commonly used in other APIs). Also you don't specify the length because it is determined from the names.
It doesn't really -- NA_INTEGER is defined to be R_NaInt. In theory NA_INTEGER being a macro could be a constant instead -- maybe for efficiency -- but currently it's not.
I guess you mean wrt PROTECT? Preserve/Release is used for objects that you want to be globally preserved - i.e. they will survive exit from the function. In contrast, the protection stack is popped when you exit the function (both by error or success).

Cheers,
Simon
#
FWIW: I have put the (slightly updated) sheet at

http://r.research.att.com/man/R-API-cheat-sheet.pdf

Note that it is certainly incomplete - but that is intentional to a) to fit the space constraints and b) to show only the most basic things since we are talking about starting with .Call -- advanced users may need a different sheet but then they just go straight to the headers anyway ...

Cheers,
Simon
On Mar 27, 2012, at 12:20 PM, Simon Urbanek wrote: