[R] Can this loop be delooped?

jim holtman jholtman at gmail.com
Fri Feb 2 00:04:14 CET 2007


This might do what you want:

> # test data
> x <- 1:43
> nb <- 5  # number of subsets
> # create vector of lengths of subsets
> ns <- rep(length(x) %/% nb, nb)
> # see if we have to adjust counts of initial subsets
> if ((.offset <- length(x) %% nb) != 0) ns[1:.offset] = ns[1:.offset] + 1
> # create the subsets
> split(x, rep(1:nb,ns))
$`1`
[1] 1 2 3 4 5 6 7 8 9

$`2`
[1] 10 11 12 13 14 15 16 17 18

$`3`
[1] 19 20 21 22 23 24 25 26 27

$`4`
[1] 28 29 30 31 32 33 34 35

$`5`
[1] 36 37 38 39 40 41 42 43



On 2/1/07, Talbot Katz <topkatz at msn.com> wrote:
> Hi.
>
> I have the following code in a loop.  It splits a vector into subvectors of
> equal size.  But if the size of the original vector is not an exact multiple
> of the desired subvector size, then the first few subvectors have one more
> element than the last few.  I know that the cut function could be used to
> determine where to break up the vector, but it doesn't seem to provide
> control over where to put the larger and smaller subvectors.
>
> numgp1_v=sidect_v%/%compmin
> numgroup_v[small]=max(1,numgp1_v[small])
> sidemin_v=sidect_v%/%numgroup_v
> nummax_v=sidect_v%%sidemin_v
> eix=0
> smallindexlist<-list(NULL)
> for(i in 1:numgroup_v[small])   {
>        bix=eix+1
>        eix=bix+sidemin_v[small]+(i<=nummax_v[small])-1
>        smallindexlist[[i]]<-dlpo_sm_v[bix:eix]
> }
>
> The key fact is that smallindexlist is a list, each list element is a
> subvector of dlpo_sm_v of the proper size.  The sizes may be different.
>
>
> I tried to see whether I could eliminate the loop, as follows.  First I
> defined a function:
>
> intgpi  <-      function(totalength,numgroups,groupnum,place="LEFT")    {
> #       function to split the integer sequence, 1:totalength, into the groupnum
> group out of numgroups groups of equal size, totalength%/%numgroups
> #       there are totalength%%numgroups number of groups of length
> 1+totalength%/%numgroups, with the large groups all to one side, left if
> place=LEFT
> #       totalength >= numgroups >= groupnum all integers, or it won't work right
>        if(charmatch(toupper(place),"RIGHT",nomatch=FALSE)==1){
>                extra1_1=max((groupnum-1)+((totalength%%numgroups)-numgroups),0)
>                extra1_2=(groupnum>numgroups-totalength%%numgroups)
>        }
>        else{
>                extra1_1=min(totalength%%numgroups,groupnum-1)
>                extra1_2=(groupnum<=totalength%%numgroups)
>        }
>        gsize=totalength%/%numgroups
>        gleft=((groupnum-1)*gsize)+extra1_1+1
>        gright=gleft+gsize+extra1_2-1
>        gleft:gright
> }
>
>
> The function appears to work okay.  Then I used it as follows:
>
> numgp1_v=sidect_v%/%compmin
> numgroup_v[small]=max(1,numgp1_v[small])
> smallindexlist<-list(NULL)
> smallindexlist=sapply(1:numgroup_v[small],function(i){dlpo_sm_v[intgpi(sidect_v[small],numgroup_v[small],i)]})
>
> In this case, smallindexlist will be a list like I had before if the
> subvectors are not all the same size, but if the subvectors are all the same
> size, it appears that I get an array.  Can I force this operation to give me
> a list the way I want it in all cases?  Or is there a better way to deloop
> my original code?
>
> Thanks!
>
> --  TMK  --
> 212-460-5430    home
> 917-656-5351    cell
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>


-- 
Jim Holtman
Cincinnati, OH
+1 513 646 9390

What is the problem you are trying to solve?



More information about the R-help mailing list