试图学习R中的绳索,并且已经在努力寻找SAS宏的替代品。
我试图多次运行一段代码,但是我很难过,来到这里寻求帮助。
首先,我正在使用此示例文件,它的一个变量为我提供了先前在另一个文件中已解析的行数(qtde_registros),然后是三个变量,这些变量为我提供了具有不同类型错误的行数。
file <- readRDS(file="file.Rda")
file
qtde_registros error1 error2 error3
1 1175 0 0 0
之后,我创建了一个包含错误的列表,另一个创建了每个错误的描述。然后,我希望使用这些列表和最初提到的文件,创建几个文件(每个错误一个),然后将其绑定到最后一个文件中以形成最终报告。
就像我说的那样,我很努力,所以我制作了一个示例代码来说明如何形成第一个文件:
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
家庭中有特定的结果。以下是该*apply
族及其输入/输出的简短列表(不完整):
lapply
->列表输出sapply
->列表或原子(整数向量,数字向量等)mapply
->类似于,sapply
但是可能需要多个输入(例如,如果您要循环两个类似的东西)tapply
->循环定义的组 INDEX
apply
->遍历数组(行或列)返回矩阵/向量等等。
我猜您的示例不完整,但是我将展示3个示例来帮助您入门。一个使用一个for-loop
,一个使用lapply
和一个使用mapply
。
for-loop
for循环是经典方法(在大多数编程语言中都可以找到)。它通过将for(---)
where---
替换为要迭代的东西来工作。可以是error_list
或可以是数字矢量seq(1, n)
或1:n
。在这里,您有1件以上的东西要迭代,因此数值向量是有意义的(并且我们使用它来对数据进行子集化)
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, errors)
使用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
现在,根据您的情况,您有1件以上的事情要进行迭代。一种替代方法是使用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个示例中,如果您读取了多个file
s或任何其他参数正在更改,则我没有考虑在内。因此,如果您必须在每次迭代中读取一个文件,则可以选择前两个示例,并readRDS
使用适当的文件命名将其添加到循环或函数中。我也使用了您的数据,但是我猜想qtde
并且error
在您的特定情况下应该有所不同,但这在您的示例中还不清楚。
我希望这会帮助您入门。
一旦您掌握了我的第一个循环的窍门,并且对它*apply
的工作方式有所了解,那么我建议您检查一下tidyverse
哪些可以提供对数据转换更“用户友好”和直观的界面。
我希望这将帮助您开始解决问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句