多次运行一段代码,更改 R 中的某些参数(如 SAS 中的宏)

标签 r

尝试学习 R 中的诀窍,并且已经在努力寻找 SAS 宏的替代品。

我试图多次运行一段代码,但我遇到了困难,所以来这里寻求帮助。

首先,我正在处理这个示例文件,其中一个变量提供了我之前在另一个文件 (qtde_registros) 中分析的行数,后面跟着三个变量提供了具有不同值的行数错误类型。

    file <- readRDS(file="file.Rda")
    file
    
      qtde_registros error1 error2 error3
    1           1175      0      0      0

之后,我创建了一个包含错误的列表和另一个包含每个错误的描述的列表。 然后,使用这些列表和最初提到的文件,我希望创建几个文件(每个错误一个),稍后将这些文件绑定(bind)到最后一个文件中以形成最终报告。

正如我所说,我正在努力解决这个问题,因此我制作了一个示例代码来说明如何形成第一个文件:

error_list <- list("Error1","Error2","Error3",)

description_list <- list("Code not found",
                        "Invalid date.",
                        "Negative value.")

error1 <- file
error1$file_name <- "Clients"
error1$error <- error_list[1]
error1$qtde <- error1$error1
error1$desc <- description_list[1]
error1 <- select(error1, file_name, error, qtde, desc)
error1

  file_name  error qtde           desc 
1   Clients Error1    0 Code not found

这引出了我的问题:如何使上面的代码运行多次,列表中的每个错误运行一次?

我知道整个心态可能不是最好的,因为根据所使用的语言,做某些事情的方法会有所不同,但我必须利用我目前拥有的知识。

我正在考虑使用 apply 系列函数,但我没有成功。

提前感谢您的帮助,并对打字或语法中的任何错误表示歉意(英语不是我的母语)。

编辑:忘了说我不打算通过 For 或 While 循环来完成。

最佳答案

在 R(以及许多其他语言)中,您将使用 for-loop 的形式。 。在 R 中,*apply 系列中有几个具有特定结果的 for 循环包装器。这是 *apply 系列及其输入/输出的简短(不完整)列表:

  • lapply -> 列出输出
  • sapply -> 列表或原子(整数向量、数值向量等)
  • mapply -> 与 sapply 类似,但可以接受超过 1 个输入来遍历(例如,如果您同时有 2 个事物需要循环)
  • tapply -> 循环 INDEX 定义的组
  • apply -> 循环数组(行或列)返回矩阵/向量

等等。

我猜您的示例不完整,但我将展示 3 个示例来帮助您入门。一种使用 for 循环,一种使用 lapply,一种使用 mapply

for循环

for 循环是经典方法(在大多数编程语言中都有)。它的工作原理是使用 for(---),其中 --- 被替换为要迭代的内容。这可以是 error_list 也可以是数值向量 seq(1, n)1:n。这里你有不止一个东西需要迭代,所以数字向量是有意义的(我们用它来子集数据)

errors <- list() # <== Somewhere to put our results
for(i in 1:length(error_list)){
  error_i <- list(file = file, 
                  file_name = "Clients",
                  error = error_list[[i]], # Use i to subset error_list
                  qtde = error_list[[i]], # Maybe this should be something else in your case
                  desc = description_list[[i]]
                  )
  # Put into our errors list. Create "error1" using paste and our index
  errors[[paste0('error', i)]] <- error_i 
}

最后,所有结果都将位于 errors 列表中,并使用 errors[1]errors["errors1"]< 进行提取 (将数字更改为您的错误)。然后可以使用 do.call(rbind, error) 组合,然后使用 write.table (或 write.csv 或类似的)保存.

lapply

对于 *apply 系列,*apply 负责循环。但我们必须提供一个在每次迭代中执行的函数(SAS 术语中的宏)。因此,我们将循环的内容包装在上面的函数中。

macro <- function(i){
 list(file = file, 
      file_name = "Clients",
      error = error_list[[i]], # Use i to subset error_list
      qtde = error_list[[i]], # Maybe this should be something else in your case?
      desc = description_list[[i]]
      )
}
errors <- lapply(1:length(error_list), macro)
#set names afterwards
names(errors) <- paste0("error", 1:length(error_list))

我们再次准备好要提取的数据并保存等。这相当于:

errors <- list()
for(i in 1:length(error_list))
  errors[[i]] <- macro(i)
names(errors) <- paste0("error", 1:length(error_list))

映射

现在,在您的情况下,您有不止一件事需要迭代。另一种方法是使用 mapply 并将它们作为参数添加到您的函数中。这样我们就可以从函数中删除 error_list[[i]]description_list[[i]] 并将它们添加为参数

macro_mapply <- function(error, description){
 list(file = file, 
      file_name = "Clients",
      error = error, # No need to use I here anymore
      qtde = error, # Maybe this should be something else in your case?
      desc = description
      )
}
errors <- mapply(macro_mapply, 
                 # parameters to iterate over comes after function
                 error = error_list, 
                 description = description_list,
                 # Avoid simplification (if we want a list returned)
                 SIMPLIFY = FALSE)
names(errors) <- paste0("error", 1:length(error_list))

请注意,如果可能,“mapply”将尝试返回向量,因此我设置 SIMPLIFY = FALSE 来避免这种情况。

注意事项:

在上面的 3 个示例中,我没有考虑您是否读取多个文件,或任何其他参数发生变化。因此,如果您必须在每次迭代中读取文件,那么使用前 2 个示例并将 readRDS 添加到具有适当文件命名的循环或函数中是有意义的。我也使用了您的数据,但我猜测 qtdeerror 在您的具体情况下应该有所不同,但这从您的示例中并不清楚。

我希望这能帮助您入门。

一旦您掌握了第一个循环的窍门,并且对 *apply 的工作原理有所了解,我建议您查看 tidyverse它提供了许多人认为更“用户友好”且直观的数据转换界面。

我希望这将帮助您开始解决您的问题。

关于多次运行一段代码,更改 R 中的某些参数(如 SAS 中的宏),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66583564/

相关文章:

r - 将向量的所有组合粘贴到R中

r - 打印脚本在 R 中运行的时间

r - 如何使用多个键定义 data.table 键以实现最快聚合

r - 将自定义列添加到 gtsummary

r - theme_bw() 去除了我的 ggplot 上的所有颜色

R:如何将列表拆分为 AM/PM

无法读取字符串的字符,除了第一个从 r 调用 c 过程的字符

r - 为 R 安装 data.table 时出现问题

regex - 在 R 中使用 gsub 删除一对括号内的任何内容

database - 将单列 R 对象写入预先存在的 postgres 数据库表中