【发布时间】:2016-08-22 12:26:04
【问题描述】:
我正在使用 R-Studio 0.99.491 和 R 版本 3.2.3 (2015-12-10)。我是 R 的相对新手,我会很感激一些帮助。我正在做一个项目,我试图在旧媒体服务器上使用服务器日志来识别服务器中的哪些文件夹/文件仍在被访问,哪些不是,以便我的团队知道要迁移哪些文件。每个日志都是 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 循环之外保存/传递,但每次循环运行时都会以某种方式被覆盖。所以我没有得到一个大的data.frame,而是得到最后一个'uriraw'文件的内容。 (这就是为什么循环中有这两个注释打印命令的原因;我正在测试每次循环运行时数据帧中有多少行。)
谁能澄清我做错了什么?同样,我希望最后有一个大的 data.frame,它结合了文件夹中每个(当前七个)日志文件的内容。
【问题讨论】:
-
uridata保持不变,因为函数在 R 中没有副作用,这是函数式编程最重要的特性之一。正如@rawr 指出的那样,您可以改为do.call("rbind", lapply(files, read.table, skip = 3, header = T, stringsAsFactors = F))做这样的事情。或者,如果您将您的lapply函数替换为for loop,您的代码将起作用。 -
在
*apply函数中创建的变量的作用域是该函数,除非您使用<<-,通常不建议这样做。通常的策略是使用lapply将list of data.frames 与list_of_data.frames <- lapply(files, function(x){read.table(x, skip = 3, header = TRUE, stringsAsFactors = FALSE)})类似,然后将它们与do.call(rbind, list_of_data.frames)组合成一个单独的data.frame。
标签: r dataframe lapply read.table rbind