0

Referencing this question:

How to reshape data from long to wide format

set.seed(45)
dat1 <- data.frame(
  name = rep(c("firstName", "secondName"), each=4),
  timeperiod = c("Q1","Q2","Q3","Q4"),
  height = c(2,9,1,2,11,15,16,10),
weight=c(1,4,2,8,2,9,1,2)
  )

dat1


    name       timeperiod height weight
1  firstName         Q1      2      1
2  firstName         Q2      9      4
3  firstName         Q3      1      2
4  firstName         Q4      2      8
5 secondName         Q1     11      2
6 secondName         Q2     15      9
7 secondName         Q3     16      1
8 secondName         Q4     10      2

Suppose I have the dataframe above with the generation code provided.

I want a dataset which is structured:

  name        Variable   Q1        Q2         Q3       Q4
  firstName  height      2         9          1         2
  firstName  weight      1         4          2         8
  secondName height      11        15         16        10
  secondName weight      2         9          1         2

Looking for a solution using base R not tidyverse. Trying to do this with the reshape function but open to other base R functions.

Mark
  • 639
  • 1
  • 6
  • 15

3 Answers3

3

We may need to reshape to 'long' before converting to 'wide'

library(dplyr)
library(tidyr)
dat1 %>% 
    pivot_longer(cols = c(height, weight), names_to = 'Variable') %>% 
    pivot_wider(names_from = "timeperiod", values_from = "value")

-output

# A tibble: 4 x 6
  name       Variable    Q1    Q2    Q3    Q4
  <chr>      <chr>    <dbl> <dbl> <dbl> <dbl>
1 firstName  height       2     9     1     2
2 firstName  weight       1     4     2     8
3 secondName height      11    15    16    10
4 secondName weight       2     9     1     2

Or using reshape in base R

names(dat1)[3:4] <- c("1_height", "1_weight")
reshape(reshape(dat1, direction = 'long', varying = 3:4, 
     sep = "_")[-5], direction = "wide", 
    idvar = c("name", "time"), timevar = "timeperiod")
akrun
  • 874,273
  • 37
  • 540
  • 662
3

base R:

One way can be:

reshape(cbind(dat1[1:2], stack(dat1, 3:4)), timevar = 'timeperiod',
        dir = 'wide', idvar = c('name', 'ind'))

         name    ind values.Q1 values.Q2 values.Q3 values.Q4
1   firstName height         2         9         1         2
5  secondName height        11        15        16        10
9   firstName weight         1         4         2         8
13 secondName weight         2         9         1         2

If using other packages, consider recast function from reshape package:

reshape2::recast(dat1, name+variable~timeperiod, id.var = c('name', 'timeperiod'))
        name variable Q1 Q2 Q3 Q4
1  firstName   height  2  9  1  2
2  firstName   weight  1  4  2  8
3 secondName   height 11 15 16 10
4 secondName   weight  2  9  1  2
Onyambu
  • 67,392
  • 3
  • 24
  • 53
1

Here is another Tidyr example

dat1 %>% 
  tidyr::gather(variable, Amount,  - name ,-timeperiod) %>%
  tidyr::spread(timeperiod, Amount, fill = 0)

KBE11416
  • 127
  • 7