0

I would like to reshape my data frame from wide to long format. I am using reshape but it's not working.

My data:

mydata = data.frame(number_p = c(1,2,3,4,1,2,3,4,5,6), SpeciesName = c('speciesA', 'speciesA', 'speciesA', 'speciesA', 'speciesB', 'speciesB', 'speciesB','speciesB', 'speciesB', 'speciesB'  ), ID =c(21,5,7,2,67,20, 13,8,9,10), Sex = c("F","M",'F','F','F','M','M','F','M','M'), head1 = rnorm(10), arm1 = rnorm(10), head2 = rnorm(10), arm2 = rnorm(10), head3 = rnorm(10), arm3 = rnorm(10))

mydata[10,10] <- NA

 number_p SpeciesName ID Sex       head1        arm1       head2       arm2       head3        arm3
         1    speciesA 21   F -0.04429807 -0.05853835  1.54179600  0.8117617 -0.86534318 -0.60921926
         2    speciesA  5   M  0.08260548  1.83582168  0.19231554 -1.7060673  0.69489476  0.57185597
         3    speciesA  7   F -2.11286648  2.10925046 -1.01523852  0.7966169 -0.31887194 -1.02658814
         4    speciesA  2   F -0.45398719  0.22426142 -0.32397390  1.1870277 -0.58044010  2.50738373
         1    speciesB 67   F -1.21285340  1.01541930 -1.13061814 -1.5060220 -0.81109484  0.66018056
         2    speciesB 20   M -0.67134622 -0.38658917 -1.28696068  0.7555496  0.54111590 -0.52281114
         3    speciesB 13   M -0.44970080 -0.37938668 -0.67067213 -0.2718157  0.06713899 -0.55882959
         4    speciesB  8   F  0.98978021 -0.42131181  0.08257053  0.5030806  0.86330772  0.03381034
         5    speciesB  9   M -0.27498650 -0.42110461 -0.67824663  1.0177662  1.75824642 -0.73827947
         6    speciesB 10   M  0.46683578 -0.36010633 -0.09015188 -1.8625175  0.43986395  NA

I would like to convert the data frame above to have the variables (head1, arm1, head2, arm2, head3, arm3)in rows by ID, for example:

        trait      ID     Sex  SpeciesName number_p
head1  -0.04429807  21     F    SpeciesA        1
arm1   -0.05853835  21     F    SpeciesA        1
head2   1.54179600  21     F    SpeciesA        1
arm2    0.81176170  21     F    SpeciesA        1
head3  -0.86534318  21     F    SpeciesA        1
arm3   -0.60921926  21     F    SpeciesA        1
head1   0.08260548   5     M    SpeciesA        2
arm1   1.83582168    5     M    SpeciesA        2
head2   0.19231554   5     M    SpeciesA        2
arm2   -1.70606730   5     M    SpeciesA        2
head3  0.69489476    5     M    SpeciesA        2
arm3   0.57185597    5     M    SpeciesA        2
.         .          .     .        .           . 
.         .          .     .        .           .     
.         .          .     .        .           .
head1   0.46683578  10     M    SpeciesB        6
arm1   -0.36010633  10     M    SpeciesB        6
head2  -0.09015188  10     M    SpeciesB        6 
arm2   -1.8625175   10     M    SpeciesB        6
head3  0.43986395   10     M    SpeciesB        6 
arm3       NA       10     M    SpeciesB        6 

The row names can be the trait name (as in my example) or a number for each trait. For example: 1 for head1, 2 for arm1, 3 for head2, 4 for arm2, 5 for head3, 6 for arm3.

BMT
  • 65
  • 6
  • 1
    Just use `pivot_longer` `library(tidyr);mydata %>% pivot_longer(cols = head1:arm3, values_to = "trait")` – akrun Mar 01 '22 at 20:51
  • Thanks, @akrun. You are always up to help here. Using `reshape` (base R) is deprecated? I like the tidy library but I am not very used to it. Also, if it's not too much here, it's possible to have the long format dataframes for each species? For example one table for speciesA and the other for species B... and so on (I have 40 species). – BMT Mar 02 '22 at 02:19
  • 1
    Not clear about the `species` part. Perhaps you can `split` by `SpeciesName` and apply the `pivot_longer` i..e `split(mydata, mydata$SpeciesName) %>% purrr::map(~ .x %>% pivot_longer(cols = head1:arm3, values_to = "trait"))` returns a `list` of data.frame/tibbles – akrun Mar 02 '22 at 15:26
  • It worked perfectly, thanks @akrun! Your responses are always helpful and inspiring to understand better R syntax, script structures, and packages. – BMT Mar 02 '22 at 16:03

0 Answers0