热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

拆分`...`参数并分配给多个函数-Splitup`…`argumentsanddistributetomultiplefunctions

Usingthefollowingfunctionfoo()asasimpleexample,Idliketodistributethevaluesgivenin.

Using the following function foo() as a simple example, I'd like to distribute the values given in ... two different functions, if possible.

使用以下函数foo()作为一个简单的例子,如果可能的话,我想分发两个不同函数中给出的值。

foo <- function(x, y, ...) {
    list(sum = sum(x, ...), grep = grep("abc", y, ...))
}

In the following example, I would like na.rm to be passed to sum(), and value to be passed to grep(). But I get an error for an unused argument in grep().

在下面的示例中,我希望将na.rm传递给sum(),并将值传递给grep()。但是我在grep()中得到一个未使用的参数的错误。

X <- c(1:5, NA, 6:10)
Y <- "xyzabcxyz"
foo(X, Y, na.rm = TRUE, value = TRUE)
# Error in grep("abc", y, ...) : unused argument (na.rm = TRUE)

It seems like the arguments were sent to grep() first. Is that correct? I would think R would see and evaluate sum() first, and return an error for that case.

似乎首先将参数发送给grep()。那是对的吗?我认为R会首先看到并评估sum(),并为该情况返回一个错误。

Furthermore, when trying to split up the arguments in ..., I ran into trouble. sum()'s formal arguments are NULL because it is a .Primitive, and therefore I cannot use

此外,当试图将论点分开......时,我遇到了麻烦。 sum()的形式参数是NULL,因为它是.Primitive,因此我无法使用

names(formals(sum)) %in% names(list(...))

I also don't want to assume that the leftover arguments from

我也不想假设剩下的论据来自

names(formals(grep)) %in% names(list(...))

are to automatically be passed to sum().

将自动传递给sum()。

How can I safely and efficiently distribute ... arguments to multiple functions so that no unnecessary evaluations are made?

如何安全有效地将...参数分配给多个函数,以便不进行不必要的评估?

In the long-run, I'd like to be able to apply this to functions with a long list of ... arguments, similar to those of download.file() and scan().

从长远来看,我希望能够将它应用于具有一长串...参数的函数,类似于download.file()和scan()。

3 个解决方案

#1


23  

Separate Lists If you really want to pass different sets of parameters to different functions then it's probably cleaner to specify separate lists:

单独的列表如果您确实想要将不同的参数集传递给不同的函数,那么指定单独的列表可能更简洁:

foo <- function(x, y, sum = list(), grep = list()) {
 list(sum = do.call("sum", c(x, sum)), grep = do.call("grep", c("abc", y, grep)))
}

# test

X <- c(1:5, NA, 6:10)
Y <- "xyzabcxyz"
foo(X, Y, sum = list(na.rm = TRUE), grep = list(value = TRUE))

## $sum
## [1] 55
## 
## $grep
## [1] "xyzabcxyz"

Hybrid list / ... An alternative is that we could use ... for one of these and then specify the other as a list, particularly in the case that one of them is frequently used and the other is infrequently used. The frequently used one would be passed via ... and the infrequently used via a list. e.g.

混合列表/ ...另一种选择是我们可以使用...作为其中之一,然后将另一个指定为列表,特别是在经常使用其中一个而另一个不经常使用的情况下。经常使用的一个将通过...传递,并且通过列表不经常使用。例如

foo <- function(x, y, sum = list(), ...) {
 list(sum = do.call("sum", c(x, sum)), grep = grep("abc", y, ...))
}

foo(X, Y, sum = list(na.rm = TRUE), value = TRUE)

Here are a couple of examples of the hybrid approach from R itself:

以下是R本身的混合方法的几个例子:

i) The mapply function takes that approach using both ... and a MoreArgs list:

i)mapply函数使用...和MoreArgs列表的方法:

> args(mapply)
function (FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE) 
NULL

ii) nls also takes this approach using both ... and the control list:

ii)nls也使用这两种方法和控制列表:

> args(nls)
function (formula, data = parent.frame(), start, cOntrol= nls.control(), 
    algorithm = c("default", "plinear", "port"), trace = FALSE, 
    subset, weights, na.action, model = FALSE, lower = -Inf, 
    upper = Inf, ...) 
NULL

#2


12  

  1. Why does grep error before sum?

    为什么总和之前的grep错误?

    See that sum is a lot more accommodating with its arguments:

    看到总和更适应其论点:

    X <- c(1:5, NA, 6:10)
    sum(X, na.rm = TRUE, value = TRUE)
    ## [1] 56
    

    It doesn't failed because it doesn't care about other named arguments, so the value = TRUE simplifies to just TRUE which sums to 1. Incidentally:

    它没有失败,因为它不关心其他命名参数,所以value = TRUE简化为TRUE,总和为1.顺便说一下:

    sum(X, na.rm = TRUE)
    ## [1] 55
    
  2. How to split ... to different functions?

    如何拆分......到不同的功能?

    One method (that is very prone to error) is to look for the args for the target functions. For instance:

    一种方法(非常容易出错)是寻找目标函数的args。例如:

    foo <- function(x, y, ...){
        argnames <- names(list(...))
        sumargs <- intersect(argnames, names(as.list(args(sum))))
        grepargs <- intersect(argnames, names(as.list(args(grep))))
        list(sum = do.call(sum, c(list(x), list(...)[sumargs])),
             grep = do.call(grep, c(list("abc", y), list(...)[grepargs])))
    }
    

    This is prone to error anytime the arguments a function uses are not properly reported by args, such as S3 objects. As an example:

    只要args(例如S3对象)没有正确报告函数使用的参数,这就容易出错。举个例子:

    names(as.list(args(plot)))
    ## [1] "x"   "y"   "..." ""   
    names(as.list(args(plot.default)))
    ##  [1] "x"           "y"           "type"        "xlim"        "ylim"       
    ##  [6] "log"         "main"        "sub"         "xlab"        "ylab"       
    ## [11] "ann"         "axes"        "frame.plot"  "panel.first" "panel.last" 
    ## [16] "asp"         "..."         ""           
    

    In this case, you could substitute the appropriate S3 function. Because of this, I don't have a generalized solution for this (though I don't know that it does or does not exist).

    在这种情况下,您可以替换相应的S3函数。因此,我没有一个通用的解决方案(虽然我不知道它确实存在或不存在)。

#3


0  

You can only pass the ... argument to another function, if that other function includes all named arguments that you pass to ... or if it has a ... argument itself. So for sum, this is no problem (args(sum) returns function (..., na.rm = FALSE)). On the other hand grep has neither na.rm nor ... as an argument.

您只能将...参数传递给另一个函数,如果该其他函数包含您传递给的所有命名参数...或者它本身具有...参数。所以总和来说,这没有问题(args(sum)返回函数(...,na.rm = FALSE))。另一方面,grep既没有na.rm也没有...作为论据。

args(grep)
# function (pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE, 
#     fixed = FALSE, useBytes = FALSE, invert = FALSE) 

This does not include ... and also does not include a named argument na.rm either. A simple solution is to just define your own function mygrep as follows:

这不包括......也不包括命名参数na.rm。一个简单的解决方案是只需定义自己的函数mygrep,如下所示:

mygrep <- function (pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE, 
                    fixed = FALSE, useBytes = FALSE, invert = FALSE, ...)
  grep(pattern, x, ignore.case, perl, value, fixed, useBytes, invert)

Then it seems to work:

然后它似乎工作:

foo <- function(x, y, ...){
  list(sum = sum(x, ...), grep = mygrep("abc", y, ...))
}
X <- c(1:5, NA, 6:10)
Y <- "xyzabcxyz"
foo(X, Y, na.rm = TRUE, value = TRUE)

# $sum
# [1] 56
# 
# $grep
# [1] "xyzabcxyz"

推荐阅读
  • 集成度|窄带_信而泰OLT使用介绍网络测试仪实操
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了信而泰OLT使用介绍-网络测试仪实操相关的知识,希望对你有一定的参考价值。 ... [详细]
  • IPVlan 详解
    文章目录简介Ipvlan2同节点Ns互通Ns内与宿主机通信第三种方法Ns到节点外部结论Ipvlan31.同节点Ns互通Ns内与宿主机通信Ns内到外部网络总结源码分析ipvlan收包 ... [详细]
  • 互联网世界 9 种基本的商业模式
    互联网世界9种基本的商业模式一个商业模式是运行一个公司的方法;通过该模式的运作,一个公司能维持自己的生存,就是说,能有收益。商业模式意味着一个公司是如何通过在价值链中定位自己,从而获 ... [详细]
  • 1、背景-在项目的实施过程中,由于有dev环境和pro环境,这时会有两个redis集群,但是部分数据从甲方的三方数据库中获取存入生产环境的redis集群中,为了方便测试和数据校验, ... [详细]
  • Android JNI学习之Concepts
    2019独角兽企业重金招聘Python工程师标准ConceptsBeforeBeginningThisguideassumesthatyouare:Alreadyfamili ... [详细]
  • 启动监控MonitorTables主要存储一些监控信息(当前运行的SQL,IO统计信息,当前进程情况)比如monDevic ... [详细]
  • 利用原始socket简单实现FTP的客户端和服务器端程序
    1.设计目的本设计旨在利用原始socket简单实现FTP(FileTransferProtocol,文件传输协议)的客户端和服务器端程序,能够实现get、put、pwd、dir、cd等基 ... [详细]
  • SQL Server 2008 到底需要使用哪些端口?
    SQLServer2008到底需要使用哪些端口?-下面就来介绍下SQLServer2008中使用的端口有哪些:  首先,最常用最常见的就是1433端口。这个是数据库引擎的端口,如果 ... [详细]
  • Spring MVC定制用户登录注销实现示例
    这篇文章描述了如何实现对SpringMVCWeb应用程序的自定义用户访问(登录注销)。作为前提,建议读者阅读这篇文章,其中介 ... [详细]
  • 1、dispatch_barrier_asyncdispatch_barrier_async用于等待前面的任务执行完毕后自己才执行,而它后面的任务需等待它完成之后才执 ... [详细]
  • 一、域名解析记录说明记录类型A:用来指定域名的IPv4地址(如:8.8.8.8),如果需要将域名指向一个IP ... [详细]
  • 13Linux基本命令和配置服务器来电后自动开机
    本节所讲内容:Linux终端介绍Shell提示符BashShell基本语法基本命令的使用:ls、pwd、cd查看系统和BIOS硬件时间Linux如何获得 ... [详细]
  • linux树莓派和n1,树莓派 斐讯N1 搭建NFS
    什么是NFS?1台Linux主机的磁盘可以通过网络挂载到其他Linux主机上,实现云盘效果。NFS是一套软件和协议,同时也是一种文件系统& ... [详细]
  • 接上文http:blog.itpub.net29254281viewspace-1318239领导让开发同学鼓捣一个可配置化的后台.又回到了原来的问题如果要灵活,很多参数要 ... [详细]
  • 本文讨论了在使用Git进行版本控制时,如何提供类似CVS中自动增加版本号的功能。作者介绍了Git中的其他版本表示方式,如git describe命令,并提供了使用这些表示方式来确定文件更新情况的示例。此外,文章还介绍了启用$Id:$功能的方法,并讨论了一些开发者在使用Git时的需求和使用场景。 ... [详细]
author-avatar
不言不语都可以温柔_631
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有