使用 R 函数在全局环境中自定义输出名称

Customised output name in global environment using R functions

我是 R 编程的新手,对这个问题有点困惑。我有 3 个不同的数据库,我想从中提取 2 组测试和训练数据。我知道如何使用单独的代码行执行此操作,但这是重复性任务,因此我想使用函数自动执行此操作。

我希望我的输出名称带有数据库名称,然后是测试或训练,然后是数字,我想将它们直接导出到全局环境中。这是我编写的代码(使用 MTCARS)作为示例数据库,它不起作用。我也给出了我想要的输出

需要说明的是,这只是一个例子。我想在不同的区域自定义全局环境中 function(x) 的输出,而无需一遍又一遍地编写代码。

mydata<-mtcars
 
output_2_set_test_train <-function(x){

  library(caTools)
  i=1
  dfname <- deparse(substitute(x))

  while(i<=2){
    sample.split(x[[1]], SplitRatio = .75)->split_tag
    subset(x, split_tag==T)->> paste0(dfname,"_","train","_",i)
    subset(x, split_tag==F)->> paste0(dfname,"_","test","_",i)
    i=i+1
  }
}
 
output_2_set_test_train(mydata)

在 运行 我的函数之后,我希望我的全局环境具有以下具有此特定名称的数据框 -

#1 数据框命名 -> mydata_train_1 #2 数据框名为 -> mydata_test_1 #3 数据框命名为 -> mydata_train_2 #4 数据框命名为 -> mydata_test_2

我尝试对此进行了大量搜索,但找不到任何有用的答案。

有人可以帮我更正代码吗?

请参阅 Konrad 关于此类编码的警告以及 R 中的约定。您的代码中几乎没有任何内容是惯用的。

您需要替换这些行:

subset(x, split_tag==T)->> paste0(dfname,"_","train","_",i)
subset(x, split_tag==F)->> paste0(dfname,"_","test","_",i)

类似:

assign(paste0(dfname,"_","train","_",i), subset(x, split_tag==T), envir = globalenv())
assign(paste0(dfname,"_","test","_",i), subset(x, split_tag==F), envir = globalenv())

R 的一个重要概念是函数应该具有尽可能少的副作用。 副作用 是除 return 值之外的任何操作。

这有几个明显的例外(例如,将数据写入文件的函数,显然 需要 产生副作用)但是在 calling/global 范围几乎从来都不是一个好主意,因为 return 值 是为此的预期机制。

在您的情况下,您通常会 return 两个值的列表。连同对代码的一些其他更改,结果如下所示:

output_2_set_test_train <- function (x) {
  is_training <- caTools::sample.split(x[[1L]], SplitRatio = 0.75)
  list(
    train = subset(x, is_training),
    test = subset(x, ! is_training)
  )
}

你会像这样使用函数:

data <- output_2_set_test_train(mtcars)

现在data$train包含训练集,data$test包含测试集。

关于实施的一些注意事项:

  1. 显然,最重要的变化是我们return获取函数的值,而不是将其分配到全局环境中。
  2. 我不使用 library,因为那是另一个 global 副作用:library 全局附加包,而不是本地(如果你是对更好的方法感兴趣,请查看包“box”)。
    • 相反,我们使用 caTools::sample.split 从函数内的“caTools”包中引用这个特定函数
  3. 我删除了无用的 ==T==F 比较。
  4. 我已经完全删除了 while 循环以及与之相关的所有内容。
  5. 我已将 split_tag 重命名为 is_training,这是一个更具描述性的名称。