0
votes

I'm trying to take a long-format dataframe and create several wide-format dataframes from it according to a list of different variables.

My thought is to use mapply to pass the set of variables I want to filter by positionally to the dataset. But it doesn't look like mapply can read in the list of vars.

Data:

library(dplyr)
library(reshape2)

set.seed(1234)
data <- data.frame(
    region = sample(c("northeast","midwest","west"), 40, replace = TRUE),
    date = rep(seq(as.Date("2010-02-01"), length=4, by = "1 day"),10),
    employed = sample(50000:100000, 40, replace = T),
    girls = sample(1:40),
    guys = sample(1:40)
)

For each of the quantitative variables (employed, girls, and guys), I want to create a wide-format dataframe with dates as rows, regions as columns.

Could I use mapply to do this more succinctly than running melt and dcast separately for each of {"employed","girls", "guys"}?

For example:

mapply(function(d,y) {melt(d[,c('region','date',y)], id.vars=c('region','date'))},
    data,
    c('employed','girls','guys')
    )

tells me:

>Error in `[.default`(d, , c("region", "date", y)) : 
  incorrect number of dimensions

What I'm looking to get is a list of the wide-format dataframes; I figured mapply would be the easiest way to pass multiple arguments, but if there's a better way to go at this, I'm all for it.

Example:

$employed
        date midwest northeast   west
1 2010-02-01   62196    513366 119070
2 2010-02-02  334849    271383 160552
3 2010-02-03  187070    320594 119721
4 2010-02-04  146575    311999 310009

$girls
        date midwest northeast west
1 2010-02-01      40       154   26
2 2010-02-02      88        76   61
3 2010-02-03      67        84   39
4 2010-02-04      48        95   42

$guys
        date midwest northeast west
1 2010-02-01      16       140   43
2 2010-02-02     115        70   43
3 2010-02-03      63        64   42
4 2010-02-04      54        94   76
1
Can you show the expected output? perhaps library(data.table); setDT(data)[, indx:=1:.N, date]; dcast(data, indx+date~region, value.var=c('employed', 'girls', 'guys')) - akrun
Looks like the expected output and input dataset is not matching. Using mapply mapply(function(x,y) dcast(cbind(x,y), date~region, value.var='x', sum), list(data[1:2]), x=data[3:5], SIMPLIFY=FALSE) - akrun

1 Answers

1
votes

The old standby of split/lapply

d<-melt(data,id.vars=c("region","date"))
lapply(split(d,d$variable),function(x) dcast(x,date~region,sum))

Example data has multiple matches, so I used an aggregating function of sum.