使用 rbind() 将多个数据帧组合成一个更大的 data.frame within lapply()
Using rbind() to combine multiple data frames into one larger data.frame within lapply()
我正在使用 R-Studio 0.99.491 和 R 版本 3.2.3 (2015-12-10)。我是 R 的新手,希望得到一些帮助。我正在做一个项目,我正在尝试使用旧媒体服务器上的服务器日志来识别服务器中的哪些 folders/files 仍在被访问,哪些不是,以便我的团队知道要访问哪些文件迁移。每个日志都是24小时的,我大概有一年的日志,所以理论上我应该可以看到过去一年的所有访问。
我理想的输出是获得一个树结构或图表,它会显示我们服务器上正在使用的文件夹。我已经想出如何将一个日志(一天)作为 data.frame 读入 R,然后使用 R 中的 data.tree 包将其变成一棵树。现在,我想在创建树之前,逐一递归地遍历目录中的所有文件,并将它们添加到原始文件 data.frame 中。这是我当前的代码:
#Create the list of log files in the folder
files <- list.files(pattern = "*.log", full.names = TRUE, recursive = FALSE)
#Create a new data.frame to hold the aggregated log data
uridata <- data.frame()
#My function to go through each file, one by one, and add it to the 'uridata' df, above
lapply(files, function(x){
uriraw <- read.table(x, skip = 3, header = TRUE, stringsAsFactors = FALSE)
#print(nrow(uriraw)
uridata <- rbind(uridata, uriraw)
#print(nrow(uridata))
})
问题是,无论我尝试什么,lapply 循环内 'uridata' 的值似乎都不是 lapply 循环外的 saved/passed ,但每次循环运行时都会以某种方式被覆盖。因此,我没有得到一个大 data.frame,而是得到最后一个 'uriraw' 文件的内容。 (这就是为什么循环中有那两个注释打印命令的原因;我正在测试每次循环时数据帧中有多少行 运行。)
任何人都可以澄清我做错了什么吗?同样,我想要一个大的 data.frame 在最后结合文件夹中每个(目前七个)日志文件的内容。
do.call()
是你的朋友。
big.list.of.data.frames <- lapply(files, function(x){
read.table(x, skip = 3, header = TRUE, stringsAsFactors = FALSE)
})
或更简洁(但不易修改):
big.list.of.data.frames <- lapply(files, read.table,
skip = 3,header = TRUE,
stringsAsFactors = FALSE)
然后:
big.data.frame <- do.call(rbind,big.list.of.data.frames)
这是推荐的做事方式,因为 "growing" 在 R 中动态处理数据框很痛苦。缓慢且占用大量内存,因为每次迭代都会构建一个新框架。
另一个选项是 fread
来自 data.table
library(data.table)
rbindlist(lapply(files, fread, skip=3))
您可以使用 purrr
包中的 map_df
而不是 lapply
,直接将所有结果合并为一个数据框。
map_df(files, read.table, skip = 3, header = TRUE, stringsAsFactors = FALSE)
我正在使用 R-Studio 0.99.491 和 R 版本 3.2.3 (2015-12-10)。我是 R 的新手,希望得到一些帮助。我正在做一个项目,我正在尝试使用旧媒体服务器上的服务器日志来识别服务器中的哪些 folders/files 仍在被访问,哪些不是,以便我的团队知道要访问哪些文件迁移。每个日志都是24小时的,我大概有一年的日志,所以理论上我应该可以看到过去一年的所有访问。
我理想的输出是获得一个树结构或图表,它会显示我们服务器上正在使用的文件夹。我已经想出如何将一个日志(一天)作为 data.frame 读入 R,然后使用 R 中的 data.tree 包将其变成一棵树。现在,我想在创建树之前,逐一递归地遍历目录中的所有文件,并将它们添加到原始文件 data.frame 中。这是我当前的代码:
#Create the list of log files in the folder
files <- list.files(pattern = "*.log", full.names = TRUE, recursive = FALSE)
#Create a new data.frame to hold the aggregated log data
uridata <- data.frame()
#My function to go through each file, one by one, and add it to the 'uridata' df, above
lapply(files, function(x){
uriraw <- read.table(x, skip = 3, header = TRUE, stringsAsFactors = FALSE)
#print(nrow(uriraw)
uridata <- rbind(uridata, uriraw)
#print(nrow(uridata))
})
问题是,无论我尝试什么,lapply 循环内 'uridata' 的值似乎都不是 lapply 循环外的 saved/passed ,但每次循环运行时都会以某种方式被覆盖。因此,我没有得到一个大 data.frame,而是得到最后一个 'uriraw' 文件的内容。 (这就是为什么循环中有那两个注释打印命令的原因;我正在测试每次循环时数据帧中有多少行 运行。)
任何人都可以澄清我做错了什么吗?同样,我想要一个大的 data.frame 在最后结合文件夹中每个(目前七个)日志文件的内容。
do.call()
是你的朋友。
big.list.of.data.frames <- lapply(files, function(x){
read.table(x, skip = 3, header = TRUE, stringsAsFactors = FALSE)
})
或更简洁(但不易修改):
big.list.of.data.frames <- lapply(files, read.table,
skip = 3,header = TRUE,
stringsAsFactors = FALSE)
然后:
big.data.frame <- do.call(rbind,big.list.of.data.frames)
这是推荐的做事方式,因为 "growing" 在 R 中动态处理数据框很痛苦。缓慢且占用大量内存,因为每次迭代都会构建一个新框架。
另一个选项是 fread
来自 data.table
library(data.table)
rbindlist(lapply(files, fread, skip=3))
您可以使用 purrr
包中的 map_df
而不是 lapply
,直接将所有结果合并为一个数据框。
map_df(files, read.table, skip = 3, header = TRUE, stringsAsFactors = FALSE)