使用reshape2 :: melt和reshape2 :: dcast在用户定义的函数中调用变量

时间:2017-06-30 12:18:13

标签: r function reshape2

我想转换此数据框

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))

到另一个

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))

因此,我使用reshape2::meltreshape2::dcast来构建用户定义的函数,如下所示

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

当我使用以下功能时

乐趣(数据,颜色,对象)

我收到以下错误消息

  

melt_check出错(data,id.vars,measure.vars,variable.name,   value.name):找不到对象'颜色'

你知道我怎么解决它?我认为问题是我应该用引号调用reshape2::melt中的变量,但我不知道如何。

注1:我想保留变量的原始数字格式(即没有小数的对象和带小数点后的价格)

注2:我想说的是,我的真实代码(这只是一个简化的例子)要长得多,并涉及dplyr函数(包括enquo()和UQ()函数)。因此,此案例的解决方案应与dplyr兼容。

注意3:我不使用tidyr(我是整个tidyverse的一大乐趣),因为当前tidyr仍然使用旧语言进行功能,我与其他可能不愿意的人分享脚本使用tidyr的开发版本。

2 个答案:

答案 0 :(得分:2)

我们可以使用dcast

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

答案 1 :(得分:0)

我自己解决了这个问题(虽然我不太了解背后的原因)。 我怀疑的主要问题是将用户定义函数的变量传递给融合和dcast导致某种冲突可能是由于缺少引号(?)。 无论如何,我使用dplyr :: rename重命名变量,以便名称不再依赖于变量而是字符。在这里,您可以看到我正在申请的最终代码:

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)

虽然我找到了解决我特定问题的方法,但如果有人向我解释背后的原因,我将非常感激。

PS:我希望无论如何,新版本的tidyr很快就会准备好让这些任务变得更容易。谢谢@hadley的出色工作。