[R] Wide to long form conversion

David Winsemius dwinsemius at comcast.net
Fri Oct 7 19:30:53 CEST 2011


On Oct 7, 2011, at 7:40 AM, Gang Chen wrote:

> Jim, I really appreciate your help!
>
> I like the power of rep_n_stack, but how can I use rep_n_stack to get
> the following result?
>
>  Subj Group value Ref Var Time
> 1    S1     s     4  Me   F    1
> 2    S1     s     3  Me   F    2
> 3    S1     s     5  Me   J    1
> 4    S1     s     6  Me   J    2
> 5    S1     s     6 She   F    1
> 6    S1     s     6 She   F    2
> 7    S1     s    10 She   J    1
> 8    S1     s     9 She   J    2

I was not able to construct a one step solution with `reshape` that  
will contains all the columns. You can do it in about 4 steps by first  
making the data "long" and then adding annotation columns. Using just  
rows 1 and 26 you might get:

reshape(myData[c(1,26), ], idvar=c("Group","Subj"),
        direction="long",
        varying=2:9,
        v.names=c("value") )
         Group Subj time value
s.S1.1      s   S1    1      4
w.S26.1     w  S26    1      5
s.S1.2      s   S1    2      5
w.S26.2     w  S26    2      9
s.S1.3      s   S1    3      6
w.S26.3     w  S26    3      4
s.S1.4      s   S1    4     10
w.S26.4     w  S26    4      7
s.S1.5      s   S1    5      3
w.S26.5     w  S26    5      3
s.S1.6      s   S1    6      6
w.S26.6     w  S26    6      7
s.S1.7      s   S1    7      6
w.S26.7     w  S26    7      3
s.S1.8      s   S1    8      9
w.S26.8     w  S26    8      5

The 'time' variable is not really what you wanted but refers to the  
sequence along the original wide column names
You can add the desired  Ref, Var and Time columms with these  
constructions:

 > str(times<-rep(c(1,2), length=nrow(myData)*8 )  )
  num [1:408] 1 2 1 2 1 2 1 2 1 2 ...
 > str(times<-rep(c("F","J"), each=2, length=nrow(myData)*8 )  )
  chr [1:408] "F" "F" "J" "J" "F" "F" "J" "J" "F" "F" ...
 > str(times<-rep(c("Me","She"), each=4, length=nrow(myData)*8 )  )
  chr [1:408] "Me" "Me" "Me" "Me" "She" "She" "She" "She" ...

longData <- reshape(myData, idvar=c("Group","Subj"),
        ction="long",
        varying=2:9,
        v.names=c("value") )
longData$Time <- rep(c(1,2), length=nrow(myData)*8 )
longData$Var <- rep(c("F","J"), each=2, length=nrow(myData)*8 )
longData$Ref <- rep(c("Me","She"), each=4, length=nrow(myData)*8 )
longData <- longData[order(longData$Subj), ]

Looking at Jim Lemon's response, I think he just misinterpreted the  
structure of your data but gave you a perfectly usable response. You  
could have done much the same thing with a minor modification:

 > str(rep_n_stack(myData,matrix(c(2,3,6,7,4,5,8,9),nrow=1,byrow=TRUE)))
'data.frame':	408 obs. of  4 variables:
  $ Group : Factor w/ 2 levels "s","w": 1 1 1 1 1 1 1 1 1 1 ...
  $ Subj  : Factor w/ 51 levels "S1","S10","S11",..: 1 12 23 34 45 48  
49 50 51 2 ...
  $ group1: Factor w/ 8 levels "Me.F.1","Me.F.2",..: 1 1 1 1 1 1 1 1 1  
1 ...
  $ value1: int  4 6 7 8 10 5 13 8 6 14 ...

Now you can just split apart the 'group1' column with sub() to make  
the three specified columns.
-- 
David.

>
> On Fri, Oct 7, 2011 at 7:16 AM, Jim Lemon <jim at bitwrit.com.au> wrote:
>> On 10/07/2011 07:28 AM, Gang Chen wrote:
>>>
>>> I have some data 'myData' in wide form (attached at the end), and
>>> would like to convert it to long form. I wish to have five variables
>>> in the result:
>>>
>>> 1) Subj: factor
>>> 2) Group: between-subjects factor (2 levels: s / w)
>>> 3) Reference: within-subject factor (2 levels: Me / She)
>>> 4) F: within-subject factor (2 levels: F1 / F2)
>>> 5) J: within-subject factor (2 levels: J1 / J2)
>>
>> Hi Gang,
>> I don't know whether this is the format you want, but:
>>
>> library(prettyR)
>> rep_n_stack(mydata,matrix(c(2,3,6,7,4,5,8,9),nrow=2,byrow=TRUE))
>>
>> Jim
>>
>
> ______________________________________________
> R-help at r-project.org 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.

David Winsemius, MD
West Hartford, CT



More information about the R-help mailing list