"i"在 for 循环中循环访问 R 中的对象列表时表示的对象的访问名称



我有:

  • 目录(假设两个:A和B(,其中包含文件
  • 存储目录的两个字符对象(dir_Adir_B(
  • 一个函数,它将目录作为参数,并返回在那里找到的文件的名称列表(对我来说,这是一种不同于list.files()的方便方式(
directories <- c(dir_A, dir_B)
read_names <- function(x) {foo}

使用for循环,我想创建对象,每个对象都包含read_names()给出的不同目录的文件列表。从本质上讲,我想使用for循环来做等效的事情:

files_A <- read_names(dir_A)
files_B <- read_names(dir_B)

我写的循环如下:

for (i in directories) {
assign(paste("files_", sub('.*\_', '', deparse(substitute(i))), sep = ""), read_names(i))
}

然而,尽管在for循环之外,deparse(substitute(dir_A))返回"dir_A"(因此,如上所述编写的sub()函数将返回"A"(,但在我看来,在for循环中,substitute(i)使i不再是目录之一,而只是i

因此,deparse(substitute(i))返回"i",上面for循环的输出只有一个名为files_i的对象,它包含迭代的最后一个目录中的文件列表,因为这是files_i上最后一个被覆盖的文件。

我如何让for循环读取i在那一刻所代表的对象的名称(或者在我的情况下是名称的一部分,但它是相同的(?

我认为这里有两个问题:

  1. 如何引用list中每个元素的名称(或索引(和值;以及
  2. 如何将数据从命名的list传输到全局(或任何(环境中

1.带数据的引用名称/索引

使用for (i in directories)进行索引后,directoriesi的完整上下文(索引、名称(将丢失。一些替代方案:

for (ix in seq_along(directories)) {
directories[[ix]]             # the *value*
names(directories)[ix]        # the *name*
ix                            # the *index*
# ...
}
for (nm in names(directories)) {
directories[[nm]]             # the *value*
nm                            # the *name*
match(nm, names(directories)) # the *index*
# ...
}

如果你愿意接受类似Map的函数(一种处理类似事物列表的更惯用的方法(,那么

out <- Map(function(x, nm) {
x                              # the *value*
nm                             # the *name*
# ...
}, directories, names(directories))
out <- purrr::imap(directories, function(x, nm) {
x                              # the *value*
nm                             # the *name*
# ...
})
# there are other ways to identify the function in `purrr::` functions

注意:虽然在最后两个中使用match来获取索引非常容易,但这是一个小的范围违反,我更愿意在合理的情况下避免。它有效,我只是更喜欢其他方法。如果您想要值、名称、索引,则

out <- Map(function(x, nm, ix) {
x                              # the *value*
nm                             # the *name*
ix                             # the *index*
# ...
}, directories, names(directories), seq_along(directories))

2.将列表传输到env

在您的问题中,您这样做是为了将列表中的变量分配到另一个环境中。关于努力的一些想法:

  1. 如果它们都相似(相同的结构,不同的数据(,则不要。将它们保存在list中,并使用lapply或类似工具对它们进行整体处理。(如何列出数据帧?(

  2. 如果您确实需要将它们从列表移动到全局环境,那么list2env在这里可能很有用。

    # create my fake data
    directories <- list(a=1, b=2)
    # this is your renaming step, rename before storing in the global env
    # ... not required unless you have no names or want/need different names
    names(directories) <- paste0("files_", names(directories))
    # here the bulk of the work; you can safely ignore the return value
    list2env(directories, envir = .GlobalEnv)
    # <environment: R_GlobalEnv>
    ls()
    # [1] "directories" "files_a"     "files_b"    
    files_a
    # [1] 1
    

相关内容

  • 没有找到相关文章

最新更新