首页 > 解决方案 > 循环遍历全局环境中的数据框并将功能应用于它们

问题描述

我将解释我的代码应该做什么:

首先,我导入任意数量的具有相同列数且名称有些相似的数据框(它们是股票行情)。

其次,我创建了一个函数来更改第一列的数据类型(从因子到日期),删除一列,最后添加任意数量的列作为其他列的函数(如返回、移动平均等)

最后,由于我正在处理大量数据帧,我想通过循环将这个函数应用于所有数据帧。

现在,听起来很简单,但我在第三步中遇到了很多问题。

我在网上找到的是这样的,以获取我环境中数据框的所有名称:

dfs <- ls()[sapply(mget(ls(), .GlobalEnv), is.data.frame)]

它给出了数据帧名称的字符串向量。由于这些是字符而不是实际的数据框对象,因此我无法遍历它们,因此我添加了:

sapply( dfs, function(x) {
  get(x) <- formatear(get(x))
  })

这可能是个坏主意,因为我不熟悉 sapply 函数。

现在,我使用的 sapply 函数返回错误::

Error in get(x) <- formatear(get(x)) : 
  no se pudo encontrar la función "get<-"

我读到 get(x) 函数搜索在向量“x”上具有名称的变量,所以我想我可以这样使用它,我的错。

其中 formatear() 是我在第二步中的函数:

formatear <- function(eq){
  eq$Volume <- NULL
  eq$Date <- as.Date(eq$Date)

  nt <- eq$Adj.Close[1:nrow(eq)-1]
  nt1 <- eq$Adj.Close[2:nrow(eq)]
  eq$return <- percent(c(NA, nt1/nt-1), accuracy = 0.0001)
  return(eq) 
  }

它将数据框作为参数并返回以我打算使用的方式转换的数据框。

当我在单个数据帧上使用它时,这很好用,在我将函数的值分配给它之后,这就是我尝试将它分配给 get(x) 的原因。

接下来我想修改我的函数,这样我只需要在 sapply 中调用它,而不必使用 assign() 函数将它分配给任何东西,因此它会直接更改全局环境中的变量。像这样的东西:

sapply( dfs, function(x) {formatear(get(x))})

通过将 formatear() 更改为:

formatear <- function(eq){
  eq$Volume <- NULL
  eq$Date <- as.Date(eq$Date)

  nt <- eq$Adj.Close[1:nrow(eq)-1]
  nt1 <- eq$Adj.Close[2:nrow(eq)]
  eq$return <- percent(c(NA, nt1/nt-1), accuracy = 0.0001)
  assign(deparse(substitute(eq)), eq, envir = globalenv()) #Changed here
  }

我使用了 deparse(substitute(eq)) 因为 assign() 只需要字符串来查找全局环境中的变量。我也在网上找到了那段代码。这不起作用,它创建了具有奇怪名称的新数据框(具有正确的格式):

structure(list(Date = structure(c(16962, 16965, 16966, 16967, #this is one of the names of these new dataframes

它还返回:

In assign(deparse(substitute(eq)), eq, envir = globalenv()) : only the first element is used as variable name

它甚至没有遍历所有的数据帧,只有两个。所以这就是整个故事,我不知道还能做什么,谷歌搜索似乎没有帮助。欢迎对我解释的任何问题提出建议。另外,也许想知道是否有一种方法可以将我环境中的所有数据帧存储到一个向量中,以便我可以使用 for 循环?无论如何,提前谢谢你。

标签: r

解决方案


保持原有formatear功能

formatear <- function(eq){
  eq$Volume <- NULL
  eq$Date <- as.Date(eq$Date)
  
  nt <- eq$Adj.Close[1:nrow(eq)-1]
  nt1 <- eq$Adj.Close[2:nrow(eq)]
  eq$return <- percent(c(NA, nt1/nt-1), accuracy = 0.0001)
  return(eq) 
}

您可以使用mget获取数据框列表并使用lapply.

clean_list_data <- lapply(mget(dfs), formatear)

clean_list_data应该是您想要的格式的数据框列表。clean_list_data[[1]]您可以使用等访问单个数据框clean_list_data[[2]]。如果将数据保存在这样的列表中,而不是在全局环境中创建多个数据框,则管理数据会更容易。


推荐阅读