R 访问数据帧:这里发生了什么?

R accessing data frames: What's going on here?

R 的新手,所以可能是一个菜鸟问题。考虑以下代码,特别是 for 循环:

library(lubridate)
#Read in all site files in the directory
sitefiles <- list.files(pattern = "\.csv$")   #Get a list of all csv's in dir
sites <- list()                                #Create an empty list.
sites <- lapply(sitefiles, read.csv)          
names(sites) <- gsub("\.csv$", "", sitefiles)  #Rename the list

for (site in names(sites)){
  site$time <-  dmy_hms(site$timestamp)
      #Error: $ operator is invalid for atomic vectors
}

好的,让我们试试这个:

for (site in sites){
  site$time <-  mdy_hms(site$timestamp)
}

它似乎对列表 sites 中的数据帧 什么都不做 。特别是命令 colnames(sites[[1]]) 在 for 循环 运行 之前和之后是相同的 - 没有添加任何列。

但是,发生了变化。 Rstudio 告诉我有一个新变量,一个名为 site 的数据框,它确实添加了时间列。什么鬼???

这是怎么回事?如何成功执行此命令?

我找不到这方面的任何来源,但在本地测试它,for 循环似乎正在创建您正在迭代的列表中项目的本地副本。也许这就是迭代 names 或更确切地说 apply 的原因。

> a <- list(mtcars$cyl)
> b <- list(mtcars$mpg)
> x <- c(a, b)
> tracemem(a)
[1] "<0000000014731C68>"
> tracemem(b)
[1] "<00000000147711D8>"
> for(myList in x) { print(tracemem(myList)) }
[1] "<000000000C37E650>"
[1] "<00000000096AED50>"

site 变量保留,因为索引变量保留在周围环境中是标准行为。

lapply 的解决方案如下所示:

sites <- lapply(sites, function(x) { 
  x$time <-  dmy_hms(x$timestamp)
  x
})

This summary 帮助您对所有不同的数据类型进行子集化。

这个案例的基础知识是:

  • sites 是一个包含多个 data.frames
  • 的列表
  • lapply 采用所有这些 data.frames 并应用相同的函数
  • 之后返回这些修改后的列表 data.frames

小旁注:如果您以后依赖这些名称,您可能需要再次为列表命名...