I have the data frame 'df' and my desired solution 'out'. I am sure there is a more elegant R-way to do it - without a loop. df = data.frame(a=1:5,b=letters[1:5],c1=1:5,c2=2:6,c3=3:7,c4=4:8) mylist=NULL for(i in 1:4){ myname<-paste("c",i,sep="") mylist[[i]]<-df[c("a","b",myname)] names(mylist[[i]])<-c("a","b","c") } out<-do.call(rbind,mylist) out Thank you! -- Dimitri Liakhovitski
On Nov 24, 2014, at 3:12 PM, Dimitri Liakhovitski wrote:> I have the data frame 'df' and my desired solution 'out'. > I am sure there is a more elegant R-way to do it - without a loop. > > df = data.frame(a=1:5,b=letters[1:5],c1=1:5,c2=2:6,c3=3:7,c4=4:8) > mylist=NULL > for(i in 1:4){ > myname<-paste("c",i,sep="") > mylist[[i]]<-df[c("a","b",myname)] > names(mylist[[i]])<-c("a","b","c") > } > out<-do.call(rbind,mylist) > out >Observe the wonders of recycling in dataframes. If you wanted to drop the last column from this it would be the same modulo changing one column nmae. cbind( df[1:2], stack(df[-c(1:2)] ) ) # a b values ind 1 1 a 1 c1 2 2 b 2 c1 3 3 c 3 c1 4 4 d 4 c1 5 5 e 5 c1 6 1 a 2 c2 7 2 b 3 c2 8 3 c 4 c2 9 4 d 5 c2 10 5 e 6 c2 11 1 a 3 c3 12 2 b 4 c3 13 3 c 5 c3 14 4 d 6 c3 15 5 e 7 c3 16 1 a 4 c4 17 2 b 5 c4 18 3 c 6 c4 19 4 d 7 c4 20 5 e 8 c4 -- David Winsemius Alameda, CA, USA
If you do not want to use the loop, a function called 'reshape' may be useful: > df <- data.frame(a=1:5,b=letters[1:5],c1=1:5,c2=2:6,c3=3:7,c4=4:8) > out2 <- reshape(data=df, direction="long", varying=list(3:6), times=paste("c",1:4,sep="")) > out2 a b time c1 id 1.c1 1 a c1 1 1 2.c1 2 b c1 2 2 3.c1 3 c c1 3 3 4.c1 4 d c1 4 4 5.c1 5 e c1 5 5 1.c2 1 a c2 2 1 2.c2 2 b c2 3 2 3.c2 3 c c2 4 3 4.c2 4 d c2 5 4 5.c2 5 e c2 6 5 1.c3 1 a c3 3 1 2.c3 2 b c3 4 2 3.c3 3 c c3 5 3 4.c3 4 d c3 6 4 5.c3 5 e c3 7 5 1.c4 1 a c4 4 1 2.c4 2 b c4 5 2 3.c4 3 c c4 6 3 4.c4 4 d c4 7 4 5.c4 5 e c4 8 5 I hope this helps. Chel Hee Lee On 11/24/2014 5:12 PM, Dimitri Liakhovitski wrote:> I have the data frame 'df' and my desired solution 'out'. > I am sure there is a more elegant R-way to do it - without a loop. > > df = data.frame(a=1:5,b=letters[1:5],c1=1:5,c2=2:6,c3=3:7,c4=4:8) > mylist=NULL > for(i in 1:4){ > myname<-paste("c",i,sep="") > mylist[[i]]<-df[c("a","b",myname)] > names(mylist[[i]])<-c("a","b","c") > } > out<-do.call(rbind,mylist) > out > > Thank you! >
Thanks a lot, guys! On Tue, Nov 25, 2014 at 9:42 AM, Lee, Chel Hee <chl948 at mail.usask.ca> wrote:> If you do not want to use the loop, a function called 'reshape' may be > useful: > >> df <- data.frame(a=1:5,b=letters[1:5],c1=1:5,c2=2:6,c3=3:7,c4=4:8) >> out2 <- reshape(data=df, direction="long", varying=list(3:6), >> times=paste("c",1:4,sep="")) >> out2 > a b time c1 id > 1.c1 1 a c1 1 1 > 2.c1 2 b c1 2 2 > 3.c1 3 c c1 3 3 > 4.c1 4 d c1 4 4 > 5.c1 5 e c1 5 5 > 1.c2 1 a c2 2 1 > 2.c2 2 b c2 3 2 > 3.c2 3 c c2 4 3 > 4.c2 4 d c2 5 4 > 5.c2 5 e c2 6 5 > 1.c3 1 a c3 3 1 > 2.c3 2 b c3 4 2 > 3.c3 3 c c3 5 3 > 4.c3 4 d c3 6 4 > 5.c3 5 e c3 7 5 > 1.c4 1 a c4 4 1 > 2.c4 2 b c4 5 2 > 3.c4 3 c c4 6 3 > 4.c4 4 d c4 7 4 > 5.c4 5 e c4 8 5 > > I hope this helps. > > Chel Hee Lee > > > On 11/24/2014 5:12 PM, Dimitri Liakhovitski wrote: >> >> I have the data frame 'df' and my desired solution 'out'. >> I am sure there is a more elegant R-way to do it - without a loop. >> >> df = data.frame(a=1:5,b=letters[1:5],c1=1:5,c2=2:6,c3=3:7,c4=4:8) >> mylist=NULL >> for(i in 1:4){ >> myname<-paste("c",i,sep="") >> mylist[[i]]<-df[c("a","b",myname)] >> names(mylist[[i]])<-c("a","b","c") >> } >> out<-do.call(rbind,mylist) >> out >> >> Thank you! >> >-- Dimitri Liakhovitski