George,

My point is you don't need to create them and then grow them....

for(i=0;i<n;i++)
{
  // Creating the "id" and "lambda" vectors. I do this in every repetition
of
  // the loop.

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

PROTECT(id=allocVector(INTSXP, 4 +z));
PROTECT(lambda=allocVector(REALSXP, 4 +z));

  // ... 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);
}

~G


On Tue, Nov 5, 2013 at 1:56 PM, George Vega Yon <g.vegayon@gmail.com> wrote:

> 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@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@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@r-project.org mailing list
> >> https://stat.ethz.ch/mailman/listinfo/r-devel
> >
> >
> >
> >
> > --
> > Gabriel Becker
> > Graduate Student
> > Statistics Department
> > University of California, Davis
>



-- 
Gabriel Becker
Graduate Student
Statistics Department
University of California, Davis

	[[alternative HTML version deleted]]

