简体   繁体   中英

Calling variable in user-defined function with reshape2::melt and reshape2::dcast

I would like to convert this data frame

data <- data.frame(color=c("red","red","red","green","green","green","blue","blue","blue"),object=c("box","chair","table","box","chair","table","box","chair","table"),units=c(1:9),price=c(11.5,12.5,13.5,14.5,15.5,16.5,17.5,18.5,19.5))

to this other one

output <- data.frame(color=c("red","green","blue"),units_box=c(1,4,7),price_box=c(11.5,14.5,17.5), units_chair=c(2,5,8),price_chair=c(12.5,15.5,18.5),units_table=c(3,6,9),price_table=c(13.5,16.5,19.5))

Therefore, I am using reshape2::melt and reshape2::dcast to build a user-defined function as the following

fun<-function(df,var,group){
  r<-reshape2::melt(df,id.vars=var)
  r<-reshape2::dcast(r,var~group) 
return(r)
}

When I use the function as follows

fun(data,color,object)

I get the following error message

Error in melt_check(data, id.vars, measure.vars, variable.name, value.name) : object 'color' not found

Do you know how can I solve it? I think that the problem is that I should call the variables in reshape2::melt with quotes but I do not know how.

Note 1: I would like keep the original number format of variables (ie objects without decimals and price with one decimal)

Note 2: I would like to remark that that my real code (this is just a simplified example) is much longer and involves dplyr functions (including enquo() and UQ() functions). Therefore the solutions for this case should be compatible with dplyr .

Note 3: I do not use tidyr (I am a big fun of the whole tidyverse) because the current tidyr still use the old language for functions and I share the script with other people that might not be willing to use the development version of tidyr .

We can use dcast from data.table

library(data.table)
dcast(setDT(data), color ~object, value.var = c("units", "price"), FUN = c(length, mean))

I solved the issue by myself (although I do not know very well the reasons behind). The main problem, as I suspected was passing the variables of the user-defined function in melt and dcast cause some kind of conflict maybe due to the lack of quotes (?). Anyway I renamed the variables using dplyr::rename so that the names are not anymore depended of variables but characters. Here you can see the final code I am applying:

fun<-function(df,var,group){
  enquo_var<-enquo(var)
  enquo_group<-enquo(group)

  r<-df%>%
    reshape2::melt(., id.var=1, variable.name = "parameter")%>%
    dplyr::rename(var = UQ(enquo_var))%>%
    reshape2::dcast(data=., formula = var~parameter, value.var = "value")

return(r)
}

funx<-fun(data,color,object)

Although I found the solution to my particular problem, I would appreciate very much if someone explains me the reasons behind.

PS: I hope anyway that the new version of tidyr is ready soon to make such tasks easier. Thanks @hadley for your fantastic work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM