在r中破坏对象,用于编写软件包;像python' **或javascript'

发布于 2025-02-09 10:03:46 字数 1740 浏览 2 评论 0原文

我一直在寻找一种破坏对象的方法。这是为了在开发软件包时编写清洁代码。

我经常有一个复杂的功能系统来称呼他人等,我想让这些参数在更高级别的功能上提供给用户。

在开发r的软件包时,我最终经常写下调用其他功能的功能,最终必须使用...运算符(只能使用一次或一次。为了像这样手动重新分配对象:

someFunction1 <- function(arg1, arg2) { print(stringr::str_interp('Do something with ${arg1}, and with ${arg2}')) }

someFunction2 <- function(arg3, arg4) { print(stringr::str_interp('Do something with ${arg1}, and with ${arg2}')) }

# solution with R's ...

someHigherFunction <- function(arg5, arg6, ...) {
    # do something with arg5 and 6

    someFunction1(...)
}

# otherwise I start having to do this; and the more nested the functions get the harder it is to manage
someHigherFunction <- function(arg5, arg6, arg1, arg2, arg3, arg4) {
    # do something with arg5 and 6

    someFunction1(arg1 = arg1, arg2 = arg2)
    someFunction1(arg3 = arg3, arg4 = arg4)
}

# there is a solution using do.call but it is rather annoying

someHigherFunction <- function(arg5, arg6, arg1_2 = list(arg1 = "something", arg2 = "something else")) {
    # do something with arg5 and 6

    # not ideal but it works
    do.call(someFunction1, arg1_2)
}

javascript我们可以使用对象破坏(容易适用于位置参数),Python也可以使用它自己的** double Star Operator :

function foo(a, b) {
    console.log(a - b);
}

let args = [10, 7];

foo(...args);

还有其他用途:

let a, b, rest;
[a, b] = [10, 20];

console.log(a);
// expected output: 10

console.log(b);
// expected output: 20

[a, b, ...rest] = [10, 20, 30, 40, 50];

console.log(rest);
// expected output: Array [30,40,50]

有人在R中有任何建议吗?

I have been looking for a way to do object destructuring. This in an effort to write cleaner code when developing packages.

I often have a complex system of functions that call others etc and I want to make those arguments available at the higher level functions to the user.

When developing packages for R I end up often writing functions that call other functions and end up having to either use the ... operator (which can only be used once. Or to manually re-assign the object like so:

someFunction1 <- function(arg1, arg2) { print(stringr::str_interp('Do something with ${arg1}, and with ${arg2}')) }

someFunction2 <- function(arg3, arg4) { print(stringr::str_interp('Do something with ${arg1}, and with ${arg2}')) }

# solution with R's ...

someHigherFunction <- function(arg5, arg6, ...) {
    # do something with arg5 and 6

    someFunction1(...)
}

# otherwise I start having to do this; and the more nested the functions get the harder it is to manage
someHigherFunction <- function(arg5, arg6, arg1, arg2, arg3, arg4) {
    # do something with arg5 and 6

    someFunction1(arg1 = arg1, arg2 = arg2)
    someFunction1(arg3 = arg3, arg4 = arg4)
}

# there is a solution using do.call but it is rather annoying

someHigherFunction <- function(arg5, arg6, arg1_2 = list(arg1 = "something", arg2 = "something else")) {
    # do something with arg5 and 6

    # not ideal but it works
    do.call(someFunction1, arg1_2)
}

In JavaScript we can use object destructuring (easy for positional arguments), python has this too with it's own ** double star operator:

function foo(a, b) {
    console.log(a - b);
}

let args = [10, 7];

foo(...args);

There are other uses for this as well:

let a, b, rest;
[a, b] = [10, 20];

console.log(a);
// expected output: 10

console.log(b);
// expected output: 20

[a, b, ...rest] = [10, 20, 30, 40, 50];

console.log(rest);
// expected output: Array [30,40,50]

Does anyone have any suggestions on how to accomplish this in R? Did I miss something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

被你宠の有点坏 2025-02-16 10:03:46

在上面扩展,这种模式是否有用/可推广?

someHigherFunction4 <- function(arg5, arg6, ...) {
  
  # collect arguments passed in dots
  
  args <- match.call(expand.dots = FALSE)$...
  
  # if arguments named, subset dots to avoid unused variable error in do.call
  
  if(!is.null(names(args))) {
    
    validArgs <- formalArgs(someFunction1)
    
    do.call(someFunction1, args[validArgs])
    
  } else {
    
  # if not, pass arguments by position
    
  do.call(someFunction1, as.list(args))

  }
}

someHigherFunction4("foo", TRUE, "this", "that")
# result: "Do something with this, and with that"

someHigherFunction4("foo", TRUE, arg1 = "this", arg2 = "that", arg3 = "bar")
# result: "Do something with this, and with that"

Expanding on above, is this pattern useful/generalizable?

someHigherFunction4 <- function(arg5, arg6, ...) {
  
  # collect arguments passed in dots
  
  args <- match.call(expand.dots = FALSE)$...
  
  # if arguments named, subset dots to avoid unused variable error in do.call
  
  if(!is.null(names(args))) {
    
    validArgs <- formalArgs(someFunction1)
    
    do.call(someFunction1, args[validArgs])
    
  } else {
    
  # if not, pass arguments by position
    
  do.call(someFunction1, as.list(args))

  }
}

someHigherFunction4("foo", TRUE, "this", "that")
# result: "Do something with this, and with that"

someHigherFunction4("foo", TRUE, arg1 = "this", arg2 = "that", arg3 = "bar")
# result: "Do something with this, and with that"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文