使用字符串作为函数参数

发布于 2024-12-11 01:20:42 字数 298 浏览 0 评论 0原文

我确信这很简单,但我找不到解决方案...... 我想使用包含字符串的变量作为函数的参数。

x <- c(1:10)
myoptions <- "trim=0, na.rm=FALSE"

现在,类似的内容

foo <- mean(x, myoptions)

相同!

foo <- mean(x, trim=0, na.rm=FALSE)

应该与“提前感谢”

I'm sure this is simple, but I cannot find a solution ...
I would like to use a variable containing a character string as argument for a function.

x <- c(1:10)
myoptions <- "trim=0, na.rm=FALSE"

Now, something like

foo <- mean(x, myoptions)

should be the same as

foo <- mean(x, trim=0, na.rm=FALSE)

Thanks in advance!

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

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

发布评论

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

评论(4

等你爱我 2024-12-18 01:20:42

您可以使用evalparse

foo <- eval(parse(text = paste("mean(x,", myoptions, ")")))

You can use eval and parse:

foo <- eval(parse(text = paste("mean(x,", myoptions, ")")))
献世佛 2024-12-18 01:20:42

执行您想要的操作的更自然的方法是使用do.call。例如,

R> l[["trim"]] = 0
R> l[["na.rm"]] = FALSE
R> l[["x"]] = 1:10
##Or l <- list(trim = 0, na.rm = FALSE, x = 1:10)
R> do.call(mean, l)
 [1] 5.5

如果由于某种原因您确实想使用 myoptions 字符串,则始终可以使用 strsplit 将其强制转换为列表形式。例如,

R> y = "trim=0, na.rm=FALSE"
R> strsplit(y, ", ")
[[1]]
[1] "trim=0"      "na.rm=FALSE" 
R> strsplit(y, ", ")[[1]][1]
[1] "trim=0"

A more natural way to do what you want is to use do.call. For example,

R> l[["trim"]] = 0
R> l[["na.rm"]] = FALSE
R> l[["x"]] = 1:10
##Or l <- list(trim = 0, na.rm = FALSE, x = 1:10)
R> do.call(mean, l)
 [1] 5.5

If for some reason you really want to use a myoptions string, you could always use strsplit to coarce it into a list form. For example,

R> y = "trim=0, na.rm=FALSE"
R> strsplit(y, ", ")
[[1]]
[1] "trim=0"      "na.rm=FALSE" 
R> strsplit(y, ", ")[[1]][1]
[1] "trim=0"
清醇 2024-12-18 01:20:42

这是第三个答案,它都使用 parsealistdo.call。我提出这个新答案的动机是在参数从客户端作为字符以交互方式传递的情况下。那么我想,没有什么好办法可以不使用parse。建议使用 strsplit 解决方案,无法理解逗号 , 是否表示下一个参数或参数内的下一个参数的上下文。 strsplit 无法理解上下文,因为 strsplit 不是解析器。

这里参数可以作为 "a=c(2,4), b=3,5"list("c(a=(2,4)","b= 3","5")

#' convert and evaluate a list of char args to a list of arguments
#'
#' @param listOfCharArgs a list of chars 
#'
#' @return
#' @export
#'
#' @examples
#' myCharArgs = list('x=c(1:3,NA)',"trim=0","TRUE")
#' myArgs = callMeMaybe(myCharArgs)
#' do.call(mean,myArgs)
callMeMaybe2 = function(listOfCharArgs) {
  CharArgs = unlist(listOfCharArgs)
  if(is.null(CharArgs)) return(alist())
    .out = eval(parse(text = paste0("alist(",
      paste(parse(text=CharArgs),collapse = ","),")")))
}

myCharArgs = list('x=c(1:3,NA)',"trim=0","TRUE")
myArgs = callMeMaybe2(myCharArgs)
do.call(mean,myArgs)
 [1] 2

Here's a third answer that both uses parse, alist and do.call. My motivation for this new answer, is in the case where arguments are passed interactively from a client-side as chars. Then I guess, there is no good way around not using parse. Suggested solution with strsplit, cannot understand the context whether a comma , means next argument or next argument within an argument. strsplit does not understand context as strsplit is not a parser.

here arguments can be passed as "a=c(2,4), b=3,5" or list("c(a=(2,4)","b=3","5")

#' convert and evaluate a list of char args to a list of arguments
#'
#' @param listOfCharArgs a list of chars 
#'
#' @return
#' @export
#'
#' @examples
#' myCharArgs = list('x=c(1:3,NA)',"trim=0","TRUE")
#' myArgs = callMeMaybe(myCharArgs)
#' do.call(mean,myArgs)
callMeMaybe2 = function(listOfCharArgs) {
  CharArgs = unlist(listOfCharArgs)
  if(is.null(CharArgs)) return(alist())
    .out = eval(parse(text = paste0("alist(",
      paste(parse(text=CharArgs),collapse = ","),")")))
}

myCharArgs = list('x=c(1:3,NA)',"trim=0","TRUE")
myArgs = callMeMaybe2(myCharArgs)
do.call(mean,myArgs)
 [1] 2
许久 2024-12-18 01:20:42

使用所有的do.callevalparse(结合kohske和csgillespie的答案,以及WoDoSc 对“将逗号分隔的字符串作为 a 传递”的回答list'):

x <- c(1:10)
myoptions <- "trim = 0, na.rm = FALSE"

do.call(
  what = mean,
  args = append(list(x = x), eval(parse(text = paste0("list(", myoptions, ")"))))
)

此解决方案在更复杂的情况下可以具有相当的弹性,如下所示。

myfn <- function(x, y = 0, z = 0, ...) {
  print(paste("x:", x))
  print(paste("y:", y))
  print(paste("z:", z))
  if (length(list(...)) > 0) {
    print("other:")
    print(list(...))
  }
}

myextraargs <- paste(
  "y = c(11, 14), z = 47,",
  "t = data.frame(p = c('apple', 'plum'), j = c(7, 2), k = c(3, 21))"
)

do.call(
  what = myfn,
  args = append(
    list(x = 7),
    eval(parse(text = paste0("list(", myextraargs, ")")))
  )
)

结果是:

[1] "x: 7"
[1] "y: 11" "y: 14"
[1] "z: 47"
[1] "other:"
$t
      p j  k
1 apple 7  3
2  plum 2 21

...并且...

myextraargs <- NULL

do.call(
  what = myfn,
  args = append(
    list(x = 7),
    eval(parse(text = paste0("list(", myextraargs, ")")))
  )
)

结果

[1] "x: 7"
[1] "y: 0"
[1] "z: 0"

Using all of do.call, eval and parse (combining kohske's and csgillespie's answers, and also WoDoSc's answer to 'Pass a comma separated string as a list'):

x <- c(1:10)
myoptions <- "trim = 0, na.rm = FALSE"

do.call(
  what = mean,
  args = append(list(x = x), eval(parse(text = paste0("list(", myoptions, ")"))))
)

This solution can be quite resilient in a more complex case, such as shown below.

myfn <- function(x, y = 0, z = 0, ...) {
  print(paste("x:", x))
  print(paste("y:", y))
  print(paste("z:", z))
  if (length(list(...)) > 0) {
    print("other:")
    print(list(...))
  }
}

myextraargs <- paste(
  "y = c(11, 14), z = 47,",
  "t = data.frame(p = c('apple', 'plum'), j = c(7, 2), k = c(3, 21))"
)

do.call(
  what = myfn,
  args = append(
    list(x = 7),
    eval(parse(text = paste0("list(", myextraargs, ")")))
  )
)

results in:

[1] "x: 7"
[1] "y: 11" "y: 14"
[1] "z: 47"
[1] "other:"
$t
      p j  k
1 apple 7  3
2  plum 2 21

...and...

myextraargs <- NULL

do.call(
  what = myfn,
  args = append(
    list(x = 7),
    eval(parse(text = paste0("list(", myextraargs, ")")))
  )
)

results in

[1] "x: 7"
[1] "y: 0"
[1] "z: 0"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文