From g.vegayon at gmail.com  Tue Nov  5 22:56:13 2013
From: g.vegayon at gmail.com (George Vega Yon)
Date: Tue, 5 Nov 2013 18:56:13 -0300
Subject: [Rd] Dynamic list creation (SEXP in C) returns error
 "unimplemented type (29) in 'duplicate'"
In-Reply-To: <CADwqtCNS8NMWz2y+88QCG6Q9cSy9=s7aw1RsF+iEvWz6hEYZvw@mail.gmail.com>
References: <CAPJUxXXWvDjAuoHBp=QZmX4BV2PScNuAUYm5VujervZ_bXeZqA@mail.gmail.com>
	<CADwqtCNS8NMWz2y+88QCG6Q9cSy9=s7aw1RsF+iEvWz6hEYZvw@mail.gmail.com>
Message-ID: <CAPJUxXWXFctds0veg3Ayy8bD3woWkA46Ss6JFWc_TFjRKDFTZA@mail.gmail.com>

Gabriel,

While the length (in terms of number of SEXP elements it stores) of L1
doesn't changes, the vectors within L1 do (sorry if I didn't explained
it well before).

The post was about a SEXP object that grows, in my case, every pair of
vectors in L1 (id and lambda) can change lengths, this is why I need
to reprotect them. I populate the i-th element of L1 by creating the
vectors "id" and "lambda", setting the length of these according to
some rule (that's the part where lengths change)... here is a reduced
form of my code:

//////////////////////////////////////// C
////////////////////////////////////////
const int = length(L0);
SEXP L1;
PROTECT(L1 = allocVector(VECSXP,n));
SEXP id, lambda;

// Fixing size
for(i=0;i<n;i++)
  SET_VECTOR_ELT(L1, i, allocVector(VECSXP, 2));

for(i=0;i<n;i++)
{
  // Creating the "id" and "lambda" vectors. I do this in every repetition of
  // the loop.
  PROTECT_WITH_INDEX(id=allocVector(INTSXP, 4), &ipx0);
  PROTECT_WITH_INDEX(lambda=allocVector(REALSXP, 4), &ipx1);

  // ... Some other instructions where I set the value of an integer
  // z, which tells how much do the vectors have to grow ...

  REPROTECT(SET_LENGTH(id,    length(lambda) + z), ipx0);
  REPROTECT(SET_LENGTH(lambda,length(lambda) + z), ipx1);

  // ... some lines where I fill the vectors ...

  // Storing the new vectors at the i-th element of the list
  SET_VECTOR_ELT(VECTOR_ELT(L1, i), 0, duplicate(id));
  SET_VECTOR_ELT(VECTOR_ELT(L1, i), 1, duplicate(lambda));

  // Unprotecting the "id" and "lambda" vectors
  UNPROTECT(2);
}

UNPROTECT(1);

return L1;
//////////////////////////////////////// C
////////////////////////////////////////

I can't set the length from the start because every pair of vectors in
L1 have different lengths, lengths that I cannot tell before starting
the loop.

Thanks for your help,

Regards,

George Vega Yon
+56 9 7 647 2552
http://ggvega.cl


2013/11/5 Gabriel Becker <gmbecker at ucdavis.edu>:
> George,
>
> I don't see the relevance of the stackoverflow post you linked. In the post,
> the author wanted to change the length of an existing "mother list" (matrix,
> etc), while you specifically state that the length of L1 will not change.
>
> You say that the child lists (vectors if they are INTSXP/REALSXP) are
> variable, but that is not what the linked post was about unless I am
> completely missing something.
>
> I can't really say more without knowing the details of how the vectors are
> being created and why they cannot just have the right length from the start.
>
> As for the error, that is a weird one. I imagine it means that a SEXP thinks
> that it has a type other than ones defined in Rinternals. I can't speak to
> how that could have happened from what you posted though.
>
> Sorry I can't be of more help,
> ~G
>
>
>
> On Mon, Nov 4, 2013 at 8:00 PM, George Vega Yon <g.vegayon at gmail.com> wrote:
>>
>> Dear R-devel,
>>
>> A couple of weeks ago I started to use the R C API for package
>> development. Without knowing much about C, I've been able to write
>> some routines sucessfully... until now.
>>
>> My problem consists in dynamically creating a list ("L1") of lists
>> using .Call, the tricky part is that each element of the "mother list"
>> contains two vectors (INTSXP and REALEXP types) with varying sizes;
>> sizes that I set while I'm looping over another list's ("L1") elements
>>  (input list). The steps I've follow are:
>>
>> FIRST: Create the "mother list" of size "n=length(L0)" (doesn't
>> change) and protect it as
>>   PROTECT(L1=allocVector(VECEXP, length(L0)))
>> and filling it with vectors of length two:
>>   for(i=0;i<n;i++) SET_VECTOR_ELT(L1,i, allocVector(VECSXP, 2));
>>
>> then, for each element of the mother list:
>>
>>   for(i=0;i<n;i++) {
>>
>> SECOND: By reading this post in Stackoverflow
>>
>> http://stackoverflow.com/questions/7458364/growing-an-r-matrix-inside-a-c-loop/7458516#7458516
>> I understood that it was necesary to (1) create the "child lists" and
>> protecting them with PROTECT_WITH_INDEX, and (2) changing its size
>> using SETLENGTH (Rf_lengthgets) and REPROTECT ing the lists in order
>> to tell the GC that the vectors had change.
>>
>> THIRD: Once my two vectors are done ("id" and "lambda"), assign them
>> to the i-th element of the "mother list" L1 using
>>   SET_VECTOR_ELT(VECTOR_ELT(L1,i), 0, duplicate(id));
>>   SET_VECTOR_ELT(VECTOR_ELT(L1,i), 1, duplicate(lambda));
>>
>> and unprotecting the elements protected with index: UNPROTECT(2);
>>
>> }
>>
>> FOURTH: Unprotecting the "mother list" (L1) and return it to R
>>
>> With small datasets this works fine, but after trying with bigger ones
>> R (my code) keeps failing and returning a strange error that I haven't
>> been able to identify (or find in the web)
>>
>>   "unimplemented type (29) in 'duplicate'"
>>
>> This happens right after I try to use the returned list from my
>> routine (trying to print it or building a data-frame).
>>
>> Does anyone have an idea of what am I doing wrong?
>>
>> Best regards,
>>
>> PS: I didn't wanted to copy the entire function... but if you need it
>> I can do it.
>>
>> George Vega Yon
>> +56 9 7 647 2552
>> http://ggvega.cl
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
>
>
> --
> Gabriel Becker
> Graduate Student
> Statistics Department
> University of California, Davis



[Rd] Dynamic list creation (SEXP in C) returns error "unimplemented type (29) in 'duplicate'"
George Vega Yon