33

一天前在这里的一篇文章让我想知道如何从一个函数中为全局环境中的多个对象分配值。这是我尝试使用lapplyassign可能比<<-我从未真正使用过它并且不熟悉它更安全)。

#fake data set
df <- data.frame(
  x.2=rnorm(25),
  y.2=rnorm(25),
  g=rep(factor(LETTERS[1:5]), 5)
)

#split it into a list of data frames
LIST <- split(df, df$g)

#pre-allot 5 objects in R with class data.frame()
V <- W <- X <- Y <- Z <- data.frame()

#attempt to assign the data frames in the LIST to the objects just created
lapply(seq_along(LIST), function(x) c(V, W, X, Y, Z)[x] <<- LIST[[x]])

请随时缩短我的代码的任何/所有部分以使其工作(或工作得更好/更快)。

4

2 回答 2

47

2018-10-10 更新:

执行此特定任务的最简洁的方法是list2env()像这样使用:

## Create an example list of five data.frames
df <- data.frame(x = rnorm(25),
                 g = rep(factor(LETTERS[1:5]), 5))
LIST <- split(df, df$g)

## Assign them to the global environment
list2env(LIST, envir = .GlobalEnv)

## Check that it worked
ls()
## [1] "A"    "B"    "C"    "D"    "df"   "E"    "LIST"

原始答案,演示了 assign() 的使用

你是对的,这assign()是适合这项工作的工具。它的envir参数使您可以精确控制分配发生的位置——使用<-or都不可用的控制<<-

因此,例如,要将值分配给在全局环境中X命名的对象NAME,您可以:

assign("NAME", X, envir = .GlobalEnv)

在你的情况下:

df <- data.frame(x = rnorm(25),
                 g = rep(factor(LETTERS[1:5]), 5))
LIST <- split(df, df$g)
NAMES <- c("V", "W", "X", "Y", "Z")

lapply(seq_along(LIST), 
       function(x) {
           assign(NAMES[x], LIST[[x]], envir=.GlobalEnv)
        }
)

ls()
[1] "df"    "LIST"  "NAMES" "V"     "W"     "X"     "Y"     "Z"    
于 2012-03-15T19:36:22.670 回答
0

如果您有对象名称和文件路径列表,您还可以使用mapply

object_names <- c("df_1", "df_2", "df_3")
file_paths   <- list.files({path}, pattern = ".csv", full.names = T)
    
mapply(function(df_name, file) 
           assign(df_name, read.csv(file), envir=.GlobalEnv),
       object_names,
       file_paths)
  • 我曾经list.files()在特定目录中构建所有 .csv 文件的向量。但是file_paths可以以任何方式编写或构造。
  • 如果您要读取的文件位于当前工作目录中,则file_paths可以替换为文件名的字符向量。
  • 在上面的代码中,您需要将{path}替换为所需目录路径的字符串。
于 2020-11-24T04:22:44.660 回答