Here's an alternative in base R.
## Some sample data
mydf <- data.frame(t1 = c(1, 1), t2 = c(2, 2), t3 = c(3, 3),
row.names = c("p1", "p2"))
mydf
# t1 t2 t3
# p1 1 2 3
# p2 1 2 3
## Wide to long
out <- cbind(rn = rownames(mydf), stack(mydf))
out
# rn values ind
# 1 p1 1 t1
# 2 p2 1 t1
# 3 p1 2 t2
# 4 p2 2 t2
# 5 p1 3 t3
# 6 p2 3 t3
## Long back to wide
reshape(out, direction = "wide", idvar="rn", timevar="ind")
# rn values.t1 values.t2 values.t3
# 1 p1 1 2 3
# 2 p2 1 2 3
In the long to wide version, you'll have to put the row names back as row.names
and rename the columns if you want the exact version of your input.
To do the same with "reshape2" if the column is not part of your data, but rownames
, as they are here, either add them in as a column as suggested by Underminer or use melt(as.matrix(.))
which would automatically take care of things.
library(reshape2)
## Wide to long
out <- melt(as.matrix(mydf))
out
# Var1 Var2 value
# 1 p1 t1 1
# 2 p2 t1 1
# 3 p1 t2 2
# 4 p2 t2 2
# 5 p1 t3 3
# 6 p2 t3 3
## Long to wide
dcast(out, Var1 ~ Var2, value.var="value")
# Var1 t1 t2 t3
# 1 p1 1 2 3
# 2 p2 1 2 3
Another option in base R is, of course, reshape
(which some people like to avoid). To use reshape
, the rownames
need to be a column in the data.frame
.
mydf$p <- rownames(mydf)
out <- reshape(mydf, direction = "long", idvar="p",
varying = c("t1", "t2", "t3"), sep = "")
out
# p time t
# p1.1 p1 1 1
# p2.1 p2 1 1
# p1.2 p1 2 2
# p2.2 p2 2 2
# p1.3 p1 3 3
# p2.3 p2 3 3
If you have used reshape
to make the long form, and you need to go back to the wide form, you don't need to specify other arguments since they are stored as attributes to the resulting object. You can just use:
reshape(out)
If you needed to manually specify the arguments to reshape from long to wide, it would look something like:
reshape(out, direction = "wide", idvar="p", timevar="time")