Complex data reshaping in R
Try
library(dplyr)
library(tidyr)
gather(df, Var, Val, -Year) %>%
unite(YearVar, Var, Year) %>%
mutate(indx=1) %>%
spread(YearVar, Val)%>%
select(-indx)
# A_2007 A_2008 A_2009 B_2007 B_2008 B_2009
#1 5 2 3 10 0 50
Update
For the edit, you can change the variables in the gather
gather(df, Var, Val, A:B) %>%
unite(YearVar, Var, Year) %>%
spread(YearVar, Val)
# id A_2007 A_2008 A_2009 B_2007 B_2008 B_2009
#1 1 5 2 3 10 0 50
#2 2 7 5 6 13 17 17
Here's a possible solution using data.table
v >= 1.9.5
library(data.table)
dcast(setDT(df), . ~ Year, value.var = c("A", "B"))
# . 2007_A 2008_A 2009_A 2007_B 2008_B 2009_B
# 1: . 5 2 3 10 0 50
Edit: per your new data set, simply add id
to the formula
dcast(setDT(df), id ~ Year, value.var = c("A", "B"))
# id 2007_A 2008_A 2009_A 2007_B 2008_B 2009_B
# 1: 1 5 2 3 10 0 50
# 2: 2 7 5 6 13 17 17
Good ol' base::reshape
works fine here. Just create a dummy id variable first.
df$id <- 1
reshape(df, v.names = c("A", "B"), timevar = "Year", idvar = "id", direction = "wide")
# id A.2007 B.2007 A.2008 B.2008 A.2009 B.2009
# 1 1 5 10 2 0 3 50
To save some typing, given that you specify timevar
and idvar
, you don't have to provide v.names
:
reshape(df, timevar = "Year", idvar = "id", direction = "wide")
This works for the edited data as well (which happened to have the "id" variable already).
# id A_2007 B_2007 A_2008 B_2008 A_2009 B_2009
# 1 1 5 10 2 0 3 50
# 2 2 7 13 5 17 6 17
You may also use reshape2::recast
:
recast(df, id ~ variable + Year, id.var = 1:2)