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

时间:2017-08-17 13:02:33

标签: r lubridate

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中的数据框 nothing 。特别是命令colnames(sites[[1]])在运行for循环之前和之后是相同的 - 没有添加任何列。

但是,有一个变化。 Rstudio告诉我有一个新变量,一个名为site的数据框,它有添加的列时间。到底是什么???

这里发生了什么?如何成功执行此命令?

2 个答案:

答案 0 :(得分:1)

lapply的解决方案如下所示:

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

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

了解此案例的基础知识是:

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

小方注意:如果你以后依赖这些名字,你可能需要再次列出名单......

答案 1 :(得分:0)

我找不到任何关于此的来源,但在本地测试,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变量仍然存在,因为索引变量保留在周围环境中是标准行为。