6
votes

I am working with a dataset that comes with lme4, and am trying to learn how to apply reshape2 to convert it from long to wide [full code at the end of the post].

library(lme4)
data("VerbAgg")  # load the dataset

The dataset has 9 variables; 'Anger', 'Gender', and 'id' don't vary with 'item', while 'resp', 'btype', 'situ', 'mode', and 'r2' do.

I have successfully been able to convert the dataset from long to wide format using reshape():

wide <- reshape(VerbAgg, timevar=c("item"), 
             idvar=c("id", 'Gender', 'Anger'), dir="wide")

Which yields 316 observations on 123 variables, and appears to be correctly transformed. However, I have had no success using reshape/reshape2 to reproduce the wide dataframe.

wide2 <- recast(VerbAgg, id + Gender + Anger ~ item + variable)
Using Gender, item, resp, id, btype, situ, mode, r2 as id variables
Error: Casting formula contains variables not found in molten data: Anger

I may not be 100% clear on how recast defines id variables, but I am very confused why it does not see "Anger". Similarly,

wide3 <- recast(VerbAgg, id + Gender + Anger ~ item + variable, 
               id.var = c("id", "Gender", "Anger"))
Error: Casting formula contains variables not found in molten data: item

Can anyone see what I am doing wrong? I would love to obtain a better understanding of melt/cast!

Full code:

## load the lme4 package 
library(lme4) 
data("VerbAgg")
head(VerbAgg)
names(VerbAgg) 

# Using base reshape()
wide <- reshape(VerbAgg, timevar=c("item"), 
                 idvar=c("id", 'Gender', 'Anger'), dir="wide")

# Using recast
library(reshape2)
wide2 <- recast(VerbAgg, id + Gender + Anger ~ item + variable)
wide3 <- recast(VerbAgg, id + Gender + Anger ~ item + variable, 
                id.var = c("id", "Gender", "Anger"))

# Using melt/cast
m <- melt(VerbAgg, id=c("id", "Gender", "Anger"))
wide <- o cast(m,id+Gender+Anger~...)
Aggregation requires fun.aggregate: length used as default
# Yields a list object with a length of 8? 

m <- melt(VerbAgg, id=c("id", "Gender", "Anger"), measure.vars = c(4,6,7,8,9))
wide <- dcast(m, id ~ variable)
# Yields a data frame object with 6 variables.
1
+1 because you love understand melt/castagstudy
wide yields 316 observations on 26 variables?? when I check dim(wide) I have 316 rows and 123 columns.agstudy
You'd be much better off melting and then casting - then you'll be able to more easily see what's going wrong.hadley
agstudy, you are correct. The proper dimensions are 316 rows and 123 columns. Sorry for the typo.Twitch_City
hadley, thanks for the response! We tried melt then cast but came up with some other odd behaviours. I updated the question to reflect our attempt. Obviously, I am missing something in defining the melt/cast formulas... Any ideas?Twitch_City

1 Answers

3
votes

I think the following code does what you want.

library(lme4) 
data("VerbAgg")

# Using base reshape()
wide <- reshape(VerbAgg, timevar=c("item"), 
                 idvar=c("id", 'Gender', 'Anger'), dir="wide")
dim(wide) # 316 123

# Using melt/cast
require(reshape2)
m1 <- melt(VerbAgg, id=c("id", "Gender", "Anger","item"), measure=c('resp','btype','situ','mode','r2'))
wide4 <- dcast(m1,id+Gender+Anger~item+variable)
dim(wide4) # 316 123

R> wide[1:5,1:6]
  Anger Gender id resp.S1WantCurse btype.S1WantCurse situ.S1WantCurse
1    20      M  1               no             curse            other
2    11      M  2               no             curse            other
3    17      F  3          perhaps             curse            other
4    21      F  4          perhaps             curse            other
5    17      F  5          perhaps             curse            other

R> wide4[1:5,1:6]
  id Gender Anger S1WantCurse_resp S1WantCurse_btype S1WantCurse_situ
1  1      M    20               no             curse            other
2  2      M    11               no             curse            other
3  3      F    17          perhaps             curse            other
4  4      F    21          perhaps             curse            other
5  5      F    17          perhaps             curse            other