1

I have a dataframe that looks like this:

x <- c('Jim', 'Jim', 'Jim', 'Sue', 'Sue', 'Sue')
y <- c(100, 200, 150, 40, 50, 30)
z <- c(5, 6, 4, 3, 4, 4)
num <- c(1, 2, 3, 1, 2, 3)

df <- data.frame(x,y,z,num)

And I need to transpose this so that i have a row for Jim and a row for Sue, with the values of y1, y2, y3, z1, z2, z3.

I know how to do this with data.table::dcast but the Linux server I'm using is having difficulty loading this package. Therefore, I am trying to do it with the reshape package or even just the reshape() function, but running into difficulty.

# This gives the desired result
df1 <- data.table::dcast(setDT(df), x ~ num, value.var=c('y', 'z'))

# Trying to figure out what I'm missing here...
df2 <- reshape::cast(df, num ~ x, value = c('y', 'z'))
Steven
  • 3,238
  • 21
  • 50
pyll
  • 1,688
  • 1
  • 26
  • 44
  • 1
    Using `reshape` from base R: `reshape(df, idvar = 'x', direction = 'wide', timevar = 'num')` – Jaap Feb 03 '18 at 16:53

2 Answers2

2

Admittedly, I don't know data.table all that well and reshape2 has some funky syntax (in my opinion, at least) that takes some time to learn.

I had to melt() your data frame into a better format, then use dcast() to get the final output.

library(reshape2)

> df %>%
+   melt(id.vars = c("x", "num"), measure.vars = c("y", "z")) %>%
+   dcast(x ~ paste0(.$variable, .$num), value.var = "value")
    x  y1  y2  y3 z1 z2 z3
1 Jim 100 200 150  5  6  4
2 Sue  40  50  30  3  4  4
Steven
  • 3,238
  • 21
  • 50
  • @denis, not really sure of the point of your comment when the OP already knows how to use `data.table::dcast` (and the approach isn't similar at all since there's no need to create a longer table before transforming it to a wide table). – A5C1D2H2I1M1N2O1R2T1 Feb 10 '18 at 14:37
1

Well maybe next time use aggregate from base r:

 aggregate(.~x,df[-4],I)
    x y.1 y.2 y.3 z.1 z.2 z.3
1 Jim 100 200 150   5   6   4
2 Sue  40  50  30   3   4   4
Onyambu
  • 67,392
  • 3
  • 24
  • 53