使用 reshape2::melt 和 reshape2::dcast 在用户定义的函数中调用变量
Calling variable in user-defined function with reshape2::melt and reshape2::dcast
我想转换这个数据框
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::melt
和 reshape2::dcast
构建用户定义的函数,如下所示
fun<-function(df,var,group){
r<-reshape2::melt(df,id.vars=var)
r<-reshape2::dcast(r,var~group)
return(r)
}
当我使用如下函数时
有趣(数据、颜色、对象)
我收到以下错误消息
Error in melt_check(data, id.vars, measure.vars, variable.name,
value.name) : object 'color' not found
你知道我该如何解决吗?我认为问题是我应该用引号调用 reshape2::melt
中的变量,但我不知道如何。
注意1:我想保留变量的原始数字格式(即没有小数点的对象和有一位小数的价格)
注意 2:我想指出,我的真实代码(这只是一个简化的示例)要长得多并且涉及 dplyr
个函数(包括 enquo() 和 UQ() 函数)。因此,这种情况的解决方案应该与 dplyr
兼容。
注意 3:我不使用 tidyr(我是整个 tidyverse 的一大乐趣),因为当前 tidyr
仍然使用旧语言来实现功能,我与其他可能不会使用的人共享脚本愿意使用开发版tidyr
.
我们可以使用 dcast
来自 data.table
library(data.table)
dcast(setDT(data), color ~object, value.var = c("units", "price"), FUN = c(length, mean))
我自己解决了这个问题(虽然我不太清楚背后的原因)。
正如我怀疑的那样,主要问题是在 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 的出色工作。
我想转换这个数据框
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::melt
和 reshape2::dcast
构建用户定义的函数,如下所示
fun<-function(df,var,group){
r<-reshape2::melt(df,id.vars=var)
r<-reshape2::dcast(r,var~group)
return(r)
}
当我使用如下函数时
有趣(数据、颜色、对象)
我收到以下错误消息
Error in melt_check(data, id.vars, measure.vars, variable.name, value.name) : object 'color' not found
你知道我该如何解决吗?我认为问题是我应该用引号调用 reshape2::melt
中的变量,但我不知道如何。
注意1:我想保留变量的原始数字格式(即没有小数点的对象和有一位小数的价格)
注意 2:我想指出,我的真实代码(这只是一个简化的示例)要长得多并且涉及 dplyr
个函数(包括 enquo() 和 UQ() 函数)。因此,这种情况的解决方案应该与 dplyr
兼容。
注意 3:我不使用 tidyr(我是整个 tidyverse 的一大乐趣),因为当前 tidyr
仍然使用旧语言来实现功能,我与其他可能不会使用的人共享脚本愿意使用开发版tidyr
.
我们可以使用 dcast
来自 data.table
library(data.table)
dcast(setDT(data), color ~object, value.var = c("units", "price"), FUN = c(length, mean))
我自己解决了这个问题(虽然我不太清楚背后的原因)。 正如我怀疑的那样,主要问题是在 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 的出色工作。