【问题标题】:passing multiple arguments in user defined function in R?在R中的用户定义函数中传递多个参数?
【发布时间】:2018-06-07 07:18:38
【问题描述】:

我的目标是创建一个用户定义的函数,它将数据框、月份或年份作为 x,产品类别作为 y,并返回一个包含城市前 10 名客户组的数据框。

我不想传递城市作为参数。

 toptencust <- function(df,x,y){
  library(magrittr)
  library(dplyr)

  ifelse(is.character(x)
    , df %>% 
      select_(City,Amount,Customer,Product,Year,month) %>%
      group_by_(City,Customer) %>%
      filter_(month==x & Product==y) %>% 
      summarise_(Tot_repay=sum(Amount,na.rm=T)) %>% 
      top_n(n=10)
    , df %>% 
      select_(City,Amount,Customer,Product,Year,month) %>%
      group_by_(City,Customer) %>%filter_(Year==x& Product==y) %>%
      summarise_(Tot_repay=sum(Amount,na.rm=T)) %>% 
      top_n(n=10)
    )

}

我的数据集看起来像

df <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
Customer    Date        Amount  month     City        Product  Year
A1          12/01/04    495415  January   BANGALORE   Gold     2004
A1          03/01/04    245899  January   BANGALORE   Gold     2004
A1          15/01/04    259490  January   BANGALORE   Gold     2004
A1          25/01/04    437555  January   BANGALORE   Gold     2004
A1          17/01/05    165973  January   BANGALORE   Gold     2005
A1          23/02/05    365367  February  BANGALORE   Gold     2005
A1          01/02/05    14473   February  BANGALORE   Gold     2005
A8          05/02/04    100002  February  PATNA       Silver   2004
A9          28/02/05    100003  February  CHENNAI     Silver   2005
A10         16/02/05    48759   February  CALCUTTA    Gold     2005
A11         23/02/05    208318  February  COCHIN      Gold     2005
A12         03/02/05    150281  February  BOMBAY      Gold     2005
A13         04/02/06    339078  February  BANGALORE   Gold     2006
A14         25/03/06    137835  March     BANGALORE   Gold     2006
A15         31/03/06    437120  March     CALCUTTA    Gold     2006
A16         23/03/06    103924  March     COCHIN      Gold     2006
A17         19/03/04    408467  March     BOMBAY      Gold     2004
A18         05/03/06    100000  March     BANGALORE   Silver   2006
A19         04/04/05    10000   April     BANGALORE   Platinum 2005
A20         30/04/06    10001   April     CALCUTTA    Platinum 2006
A21         25/04/04    10002   April     COCHIN      Platinum 2004
A22         19/04/06    100000  April     BOMBAY      Silver   2006
A23         06/04/04    80346   April     BANGALORE   Silver   2004
A24         27/04/05    100002  April     DELHI       Silver   2005
A25         05/05/04    100003  May       COCHIN      Silver   2004
A26         06/05/06    470982  May       PATNA       Gold     2006
A27         07/05/05    357376  May       CHENNAI     Gold     2005
A28         08/05/06    326050  May       TRIVANDRUM  Gold     2006
A29         09/05/05    215083  May       CALCUTTA    Gold     2005
A30         10/05/06    481343  May       BANGALORE   Gold     2006")

我的目标是得到如下输出

当我运行这个函数时,我收到如下错误:

toptencust(df,'February',2014)

总和错误(金额,na.rm = T):参数的“类型”(符号)无效

我无法理解问题,请帮忙?

【问题讨论】:

  • 没有线索。 consolidate 中有什么内容?我建议你阅读reproducible examples,然后编辑你的问题。
  • 但是一些提示:(1)不要在这里使用if_else,只使用if {...} else {...},这是对向量化条件函数的非常错误/低效的使用; (2) 不要将整个magrittr 管道放在一条线上,这会使阅读和调试变得更加困难。
  • 请阅读我在第一条评论中提供的链接。相对明显的是,它是一个框架或类似框架的东西,因此您可以在dplyr-pipes 中使用。如果您希望某人能够解决正在发生的事情,您需要提供更多。减少问题也很好,因为我怀疑我们不需要处理所有这些列来解决您的问题。另一个很好的参考:minimal, verifiable examples.
  • 该代码对我不起作用,因为您提供了 png,但 dplyr 函数需要 data.frame。 (您复制dput(head(mydataset)) 的输出可能就像复制屏幕截图一样简单,但是当我们可以复制/将其粘贴到 R 会话中。我不会转录它。)
  • Anubhav,现在我建议您阅读reproducible 两次,您离得更近了,但您没有采用推荐的方法。他们建议(非常清楚地)以易于使用的格式提供您的数据,dput(head(x))read.table(text='...') 是两个很好的例子。为了证明我的观点,请尝试快速轻松地读取您发布到 data.frame 中的数据,然后对我刚刚编辑的问题执行相同的操作(使用 read.table)。这样就容易多了。

标签: r dplyr


【解决方案1】:

执行你的例子,我得到另一个错误:

compat_lazy_dots(.dots, caller_env(), ...) 中的错误: 找不到对象“城市”

这是因为您使用了“逃生舱口”功能select_filter_ 等等。您可能这样做是因为您需要在filter_(month==x &amp; Product==y) 中使用变量x。但现在其他名称,如 Product,本来是数据框中的名称,也被视为变量!

这是tutorial on the old "escape hatch" functions

现在,使用 !! 运算符解决了这个问题。请参阅小插图Programming with dplyr

toptencust <- function(df,x,y){
    library(magrittr)
    library(dplyr)

    ifelse(is.character(x)
           , df %>% 
               select(City,Amount,Customer,Product,Year,month) %>%
               group_by(City,Customer) %>%
               filter(month == !!x & Product == !!y) %>% 
               summarise(Tot_repay=sum(Amount,na.rm=T)) %>% 
               top_n(n=10)
           , df %>% 
               select(City,Amount,Customer,Product,Year,month) %>%
               group_by(City,Customer) %>%
               filter(Year == !!x & Product == !!y) %>%
               summarise(Tot_repay=sum(Amount,na.rm=T)) %>% 
               top_n(n=10)
    )
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 2020-08-10
    相关资源
    最近更新 更多