【问题标题】:intelligently using the ellipsis in an R function在 R 函数中智能地使用省略号
【发布时间】:2018-01-27 00:24:09
【问题描述】:

我有一个带有这样签名的函数:

myFunction=function(class="Class",v1='y',v2='y',dfparam=df){

其中df是一个数据框,假设df中有一个名为Class的属性。我想让它更通用,以便它可以接受各种数据帧 df,而不仅仅是一个具有名为 Class 的属性的数据帧。 所以我添加了一个className参数和classValue参数来替换类参数。另外,我想允许无限的参数 v1、v2、v3 等,所以我使用这样的省略号:

myFunctionGeneral = function(className="Class", classValue="democrat", dfparam=df, ...){
  arguments <- list(...)

在使用省略号之前,我有一行使用以下参数:

X_bool=dfparam$V1==v1 & dfparam$V2==v2 

我开始这样做了:

X_bool=dfparam[,2]==arguments[1] & dfparam[,3]==arguments[2]

但我想为省略号中无限数量的可能参数执行此操作。 所以我需要通过某种方式解开省略号来扩展这个陈述。 这是一个例子:

install.packages("vcd")
library(vcd)
data(Arthritis)
AAr=Arthritis[,-c(1,4)]


myFunctionGeneral=function(className="Class",classValue="democrat",dfparam=df, ...){

  dfparam$names<-rownames(dfparam)
  arguments<-list(...)


  dfparamDroppedClass=dfparam[,-1]
  #X_bool=dfparam[,2]==arguments[1] & dfparam[,3]==arguments[2] 
  X_bool=do.call(all, Map("==", dfparamDroppedClass, arguments))


  X=dfparam[X_bool,]


}

【问题讨论】:

    标签: r function ellipsis


    【解决方案1】:

    这应该说明原理:

    arguments <- list(1, 2, 3)
    params <- list(1, 2, 3)
    do.call(all, Map("==", arguments, params))
    #[1] TRUE
    
    params <- list(1, 2, 4)
    do.call(all, Map("==", arguments, params))
    #[1] FALSE
    

    All 相当于任意数量的&amp;Map 在两个列表上迭代==

    编辑: 显然你的 data.frame 有不止一个观察。那么你不能使用all,但需要使用Reduce,如Reduce("&amp;", Map("==", arguments, params))。用你的例子:

    myFunctionGeneral=function(className="Class",classValue="democrat",dfparam=df, ...){
    
      dfparam$names<-rownames(dfparam)
      arguments<-list(...)
    
      dfparamDroppedClass=dfparam[, -c(1, 4)]
      #X_bool=dfparam[,2]==arguments[1] & dfparam[,3]==arguments[2] 
      X_bool=Reduce("&", Map("==", dfparamDroppedClass, arguments))
    
      dfparam[X_bool,]      
    }
    
    myFunctionGeneral('Treatment','Placebo',AAr,'Male','Marked')
    #   Treatment  Sex Improved names
    #4    Treated Male   Marked     4
    #5    Treated Male   Marked     5
    #6    Treated Male   Marked     6
    #8    Treated Male   Marked     8
    #14   Treated Male   Marked    14
    #52   Placebo Male   Marked    52
    

    【讨论】:

    • 谢谢。我认为 arguments
    • data.frame 也是一个列表。而且您知道如何删除 data.frame 的第一列,不是吗?
    • 谢谢!我试过这个:dfparamDroppedClass=dfparam[,-1] 然后这个:X_bool=do.call(all, Map("==", dfparamDroppedClass, arguments))。但我收到一条警告警告消息:在 mapply(FUN = f, ..., SIMPLIFY = FALSE) 中:更长的参数不是更短长度的倍数。而且我正在编写的函数也不会产生正确的输出。当我用这个运行它时: X_bool=dfparam[,2]==arguments[1] & dfparam[,3]==arguments[2] ,它似乎工作。
    • 抱歉,没有minimal reproducible example,我不会花更多时间。
    • 我这样称呼它:myFunctionGeneral('Treatment','Placebo',AAr,'Male','Marked')
    猜你喜欢
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 2014-03-28
    • 2011-03-04
    相关资源
    最近更新 更多