R 函数的多个相似输入 - 使用列表提供它们的问题

问题描述 投票:0回答:1

我有以下问题:我想编写一个应该获得多个相似输入集的函数,可以说:

FUN <- function(part1.x, part1.y, part1.z, part2.x, part2.y, part2.z){}

所以每个部分的变量是相同的,但它们可以有不同的值。我的第一次尝试是像这样使用它们,但是输入的数量不断增加,而且看起来非常复杂。我的下一个想法是将变量存储为向量,并使用元素的位置来指示它们属于哪个部分,例如

FUN <- function(x, y, z){}
,其中每个输入都是一个向量
c[part1, part2]
。这更好,但我发现很难在部件之间交换输入,感觉有点混乱。

我最喜欢的处理方式和用户友好性的想法是存储一个包含每个部分输入的列表,例如

FUN <- function(part1 = list(x, y, z), part2 = list(x, y, z){}

这里的问题是,似乎不可能将默认值与用户输入结合起来,因此当函数读取时:

FUN <- function(part1 = list(x = 1, y = TRUE, z = "abc"), part2 = list(x = 2, y = FALSE, z = "bcd")){}

并且用户执行

FUN(part1 = list(y = FALSE), part2 = list(x = 2))
,则对于
part1$x
part1$z
part2$y
part2$z
,默认值将被忽略,并且随着整个列表被覆盖,变量不存在。

作为解决方法,我为每个部分编写了一个函数,该函数基本上只是用于存储和返回默认值:

part1_fun <- function(x = 1, y = TRUE, z = "abc"){
  return(formals(part1_fun))
} 

part2_fun <- function(x = 2, y = FALSE, z = "bcd"){
  return(formals(part2_fun))
} 

然后在主函数中调用它来检索默认值,然后通过名称相等性与提供的输入进行组合:

FUN <- function(part1_args, part2_args){
  part1_default <- part1_fun(part1_args)
  part2_default <- part2_fun(part2_args)
  
  common_names_part1 <- intersect(names(part1_args), names(part1_default ))
  common_names_part2 <- intersect(names(part2_args), names(part2_default ))
  
  part1_input <- part1_default
  part1_input[common_names_part1] <- part1_args[common_names_part1]
  part2_input <- part2_default
  part2_input[common_names_part2] <- part2_args[common_names_part2]
 
  print(part1_input)
  print(part2_input)
   
}

FUN(part1_args = list(x = 3, z = "a"), part2_args = list(y = TRUE))

这可行(但感觉像是一种黑客),因为它然后使用所有值(默认值和用户提供的值),但是我已经看到的一个缺点是它不会捕获拼写错误的输入,如果我没有捕获它就会忽略它分别那个。另一个是我目前没有找到一种方法可以让 match.arg 在这种情况下工作以允许更短的输入字符串。因此,当 z 可以是两个字符串

part1_fun <- function(x = 1, y = TRUE, z = c("abc", zyx")){
之一时,在此函数中添加
z = match.arg(z)
不会导致用户输入
FUN(part1_args = list(z = "a"))
转换为 z == "abc"。相反,它仍然是“a”。

所以我的问题:

  1. 处理多个相似输入值(如我的情况)的最佳方法是什么?我觉得我可能错过了什么。有没有捷径可走?

如果情况并非如此:

  1. 我的方法是否比我已经提到的方法有更多的缺点 - 以及如何解决我发现的最好的方法?

我发现这个有点相关的帖子获取所有参数作为列表提取列表的元素作为r中自定义函数中的单独参数但我无法让它工作,并且还想确保我走在正确的轨道上根本...

谢谢!

r list function user-input default-value
1个回答
0
投票

基于

do.call()
的解决方案;等待
match.arg()
处理和更多解释。

part1_fun <- function(x = 1, y = TRUE, z = "abc"){
  list(x = x, y = y, z = z)
} 

part2_fun <- function(x = 2, y = FALSE, z = "bcd"){
  list(x = x, y = y, z = z)
} 

FUN <- function(part1_args, part2_args){
  part1_input <- do.call(part1_fun, part1_args)
  part2_input <- do.call(part2_fun, part2_args)
 
  print(part1_input)
  print(part2_input)   
}

FUN(part1_args = list(x = 3, z = "a"), part2_args = list(y = TRUE))

输出:

$x
[1] 3

$y
[1] TRUE

$z
[1] "a"

$x
[1] 2

$y
[1] TRUE

$z
[1] "bcd"
© www.soinside.com 2019 - 2024. All rights reserved.