提问人:mydeliciouspie 提问时间:3/28/2023 最后编辑:mydeliciouspie 更新时间:3/28/2023 访问量:45
通过多个函数层使用点 (“...”) 参数时出现问题
Problem with using the dots ("...") argument through multiple function layers
问:
我正在尝试将 R-functions 的 dots-argument 用于数据导入函数。该函数应获取文件路径列表,并接受进一步的参数以传递给内部使用的函数。它应该导入指定的文件并将它们绑定到一个 DataFrame 中。输出将保存到全局环境中。data_list
fread()
到目前为止的例子和想法:
我有一个文件夹“test1”,包含一个文件和一个文件夹“test2”,包含多个文件。这些文件是具有相同内部结构的 .txt 文件(在本例中为 4 行无用标头和 4 行数据),如下所示:
this is
a header
with some text
that should be ignored when importing
1;2;3;4
2;2;4;2
3;4;3;2
4;2;3;1
我生成我的列表:
data_list_1 <- list.files(path = "./test1",
recursive = TRUE,
pattern = "*.txt",
full.names = TRUE)
data_list_2 <- list.files(path = "./test2",
recursive = TRUE,
pattern = "*.txt",
full.names = TRUE)
在单个文件案例中,将参数传递给 works:fread()
data_import_test_1 <- function(data_list, ...) {
.GlobalEnv$test_import <- fread(file = data_list, ...)
}
# imagine i have a fileset where i need to skip the first 4 rows when
# importing (data_list_1 contains a single file path)
data_import_test_1(data_list = data_list_1, skip = 4)
# output created is a dataframe of the specified file
# without the first 4 rows
但是现在我想一次导入多个文件并将它们附加在一起,所以我想像这样包装它:fread()
rbind()
lapply()
data_import_test_2 <- function(data_list, ...) {
.GlobalEnv$test_import <- do.call(what = rbind,
args = lapply(data_list,
function(x, ...) fread(x, ...)))
}
# imagine i have multiple files of the same format as the single file
# from the import above and data_list_2 contains all of them
data_import_test_2(data_list = data_list_2, skip = 4)
# output created still contains the rows i wanted to skip,
# the skip = 4 argument doesnt reach fread()
有没有人知道如何处理移交,而不必将其硬编码到函数参数中?我将对来自不同来源的分割数据集使用我的函数,这些数据集需要不同的输入。这意味着我真的很想让我的函数动态地交出我需要的任何东西。
非常感谢大家看到这个,提前谢谢你!
我知道我可以像这样将参数硬编码到我的函数中:
data_import_test_2 <- function(data_list, fread_skip) {
.GlobalEnv$test_import <- do.call(what = rbind,
args = lapply(data_list,
function(x, fread_skip = fread_skip)
fread(x, skip = fread_skip)))
}
我将希望对不同的数据集使用其他参数,并且我不想将它们全部包含在我的函数参数中,因为这会导致很多混乱和可读性降低。fread
答:
1赞
Chris Cox
3/28/2023
#1
您需要使用 from 父函数传递到子函数中...
lapply(x, function(.x, ...) {do_something(.x, ...)}, ...)
例如,这将起作用:
sum_list_elements <- function(x, ...) {
lapply(x, function(.x, ...) {
sum(.x, ...)
}, ...)
}
sum_list_elements(list(c(1,2,3,NA), c(4,5,6,NA)))
sum_list_elements(list(c(1,2,3,NA), c(4,5,6,NA)), na.rm = TRUE)
这不会:
sum_list_elements_broken <- function(x, ...) {
lapply(x, function(.x, ...) {
sum(.x, ...)
})
}
sum_list_elements_broken(list(c(1,2,3,NA), c(4,5,6,NA)))
sum_list_elements_broken(list(c(1,2,3,NA), c(4,5,6,NA)), na.rm = TRUE)
评论
0赞
mydeliciouspie
3/28/2023
所以就我而言,我必须使用“......”我的 do.call() 和 lapply() 中的参数?现在就试试吧!谢谢你帮助我!编辑:do.call() 不需要也不想要我的“......”参数,但将其插入 lapply() 后,一切正常。
0赞
Chris Cox
3/29/2023
没错,你把点传进去,而不是.将点传递给 是告诉 R 将参数传递到数据帧的末尾,这不是您想要的。 和其他类似的函数允许您将“常量”参数传递给每个调用。例如,将常数 4 添加到每个数字 1:10(这不是有效的方法,只是演示一个概念)。lapply
do.call
do.call
rbind
...
lapply
lapply(1:10, `+`, 4)
评论
...
lapply
...
...
lapply(data_list, function(x, ...) fread(x, ...), ...)
lapply(data_list, fread, ...)