【问题标题】:Calling variable in user-defined function with reshape2::melt and reshape2::dcast使用 reshape2::melt 和 reshape2::dcast 在用户定义的函数中调用变量
【发布时间】:2017-06-30 12:18:12
【问题描述】:

我想转换这个数据框

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 中的错误(数据,id.vars,measure.vars,variable.name, value.name) : 找不到对象“颜色”

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

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

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

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

【问题讨论】:

    标签: r function reshape2


    【解决方案1】:

    我们可以从data.table使用dcast

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

    【讨论】:

    • 感谢@akrun 的想法,但我在使用如下函数fun&lt;-function(df,var,group){ r&lt;-reshape2::melt(df,id.vars=var) r&lt;-dcast(setDT(r), color ~object, value.var = c("units", "price"), FUN = c(length, mean)) return(r) } fun(data,color,object)时收到相同的错误消息fun&lt;-function(df,var,group){ r&lt;-reshape2::melt(df,id.vars=var) r&lt;-dcast(setDT(r), color ~object, value.var = c("units", "price"), FUN = c(length, mean)) return(r) } fun(data,color,object)
    • @ungatoverde 我在使用data.table_1.10.5 的示例中没有遇到任何错误哦,好吧,根据您的函数,fun 中的data 在哪里。我看到你创建了一个对象r
    • 对不起,你是对的。我之前的评论有误。我刚刚纠正了它。我还添加了 data.table 的正确函数名称:fun&lt;-function(df,var,group){ r&lt;-data.table::melt.data.table(df,id.vars=var) r&lt;-data.table::dcast.data.table(setDT(r), color ~object, value.var = c("units", "price"), FUN = c(length, mean)) return(r) } fun(data,color,object) 但仍然是相同的错误消息:-(
    • @ungatoverde 我不明白这里的melt。您的data 似乎已经采用long 格式。你能显示使用的输入数据吗
    • 输入数据是我的问题中提供的第一个数据框:data &lt;- 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))
    【解决方案2】:

    我自己解决了这个问题(虽然我不太清楚背后的原因)。 我怀疑的主要问题是在melt和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 的出色工作。

    【讨论】:

      猜你喜欢
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 2013-02-20
      • 2016-07-27
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      相关资源
      最近更新 更多