[R] repeat rows of matrix by number (k) in one colummatrix adding column j with values 1:k

Jim Lemon drj|m|emon @end|ng |rom gm@||@com
Wed Apr 1 06:33:39 CEST 2020


Hi Nevil,
It's a nasty piece of work, but:

M<-matrix(c(1,2,3,4,1,2,3,4,1,2,3,4,2,1,3,2),4,4,
dimnames = list(NULL, c("x", "y", "z","k")))
M
reprow<-function(x)
 return(matrix(rep(x,x[length(x)]),nrow=x[length(x)],byrow=TRUE))
toseq<-function(x) return(1:x)
j<-unlist(sapply(M[,"k"],toseq))
Mlist<-apply(M,1,reprow)
Mlist
newM<-Mlist[[1]]
for(i in 2:length(Mlist)) newM<-rbind(newM,Mlist[[i]])
newM
newM<-cbind(newM,j)
colnames(newM)<-c(colnames(M),"j")
newM

Jim

On Wed, Apr 1, 2020 at 1:43 PM nevil amos <nevil.amos using gmail.com> wrote:
>
> Well,
> I found a way to do it partly using rep(), and one loop that makes it 10x
> or more faster however would still be good to do without the loop at all
> matrix made slightly beigger (10000 rows):
>
> M<-matrix(c(1:30000
> ), 10000,3)
> M<-cbind(M,sample(1:5,size = 10000,replace = T))
> #Print(M)
> #Create matrix (Mout) in this case 8 rows with x,y,z in each row of M
> #repeated k times with column j numbered from 1:k
> # ! can do with nested loops but this is very slow ( example below)
> #How do I acheive this quickly without loops?
> print("double loop")
> print(system.time({
> Mout<-NULL
>
> for(i in 1:nrow(M)){
>   a=M[i,1:3]
>   k=M[i,4]
>   for (j in 1:k){
>     b=c(a,j)
>     Mout<-rbind(Mout,b)
>     }
> }
> colnames(Mout)<-c("x","y","z","j")
> }))
>
> print("rep and single loop")
> print(system.time({
>   j<-NULL
>   MOut<-NULL
>   MOut<-M[,1:3][rep(1:nrow(M), times = M[,4]), ]
>   for(i in M[,4])(j<-c(j,1:i))
>   MOut<-cbind(MOut,j)
>   colnames(Mout)<-c("x","y","z","j")
> }))
>
> On Wed, 1 Apr 2020 at 12:18, nevil amos <nevil.amos using gmail.com> wrote:
>
> > Hi
> >
> > I can achieve this using two for loops but it is slow  I need to do this
> > on many matrices with tens of millions of rows of x,y,z and k
> >
> > What is a faster method to achieve this, I cannot use rep as j changes in
> > each row of the new matrix
> > ###############################################
> > M<-matrix(c(1,2,3,4,1,2,3,4,1,2,3,4, 2, 1, 3, 2
> > ), 4,4, dimnames = list(NULL, c("x", "y", "z","k")))
> >
> > Print(M)
> > #Create matrix (Mout) in this case 8 rows with x,y,z in each row of M
> > #repeated k times with column j numbered from 1:k
> > # ! can do with nested loops but this is very slow ( example below)
> > #How do I acheive this quickly without loops?
> > Mout<-NULL
> >
> > for(i in 1:nrow(M)){
> >   a=M[i,c("x","y","z")]
> >   for (j in 1:M[i,"k"]){
> >     b=c(a,j)
> >     Mout<-rbind(Mout,b)
> >     }
> > }
> > colnames(Mout)[4]<-"j"
> > print(Mout)
> >
> > #########################################################
> >
> > Thanks
> >
> > Nevil Amos
> >
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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.



More information about the R-help mailing list