我需要一个包含某些文件名称的数据框,这些文件与映射到这些文件中每行的模式相匹配。我的问题是,我无法为每一行生成多行,数据框应按列和行增长,每行展开。我需要的基本上是左外连接,但我正在努力学习语法。
library(dplyr)
app.lsts <- data.frame(
file=list.files(path='.', pattern='app.lst', recursive=TRUE)
) %>%
mutate(command=paste0('cat ', file)) %>%
mutate(packages=system(command, intern=TRUE))
最后一个mutate不起作用,因为packages是一个行列表。我如何“打开”这些?
答案 0 :(得分:1)
首先,一些工作(但不是很好的代码):
require(tidyverse)
out_df <-
list.files(path='.', pattern='*.foo', recursive=TRUE) %>%
map(~readLines(file(.x))) %>%
setNames(fnames) %>%
t %>%
as.data.frame %>%
gather(file, lines) %>%
unnest()
out_df
这是一个tidyverse风格的命令,用于生成我认为您想要的数据。由于我没有您的输入文件,我编写了这些示例文件:
f1.foo
line_1_f1
line_2_f1
f2.foo
line_1_f2
line_2_f2
line_3_f2
file()
作为列名。我改为使用fname
。system
来读取文件,有内置的R函数可以做到这一点。使用system()
不必要地使您的代码移植到其他操作系统更不可能成功。在将所有数据读入R之后构建数据帧,而不是之前。由于dplyr
的非标准评估方式有效,因此在readLines(...)
内部mutate()
很难使用要读取的文件连接的purrr::map()
。
使用setNames()
从文件名列表中生成文件内容行列表。这是编写for循环的一种整合方式。
t()
设置列表元素的名称。as.data.frame()
和gather()
unnest()
整理数据,将每个文件有一列的数据框折叠到每行一个文件的数据框中。fnames <- list.files(path='.', pattern='*.foo', recursive=TRUE)
out_df <- data.frame(fname = c(), lines=c())
for(fname in fnames){
fcontents <- readLines(file(fname)) %>% as.character
this_df <- data.frame(fname = fname, lines = fcontents)
out_df <- bind_rows(out_df, this_df)
}
展开列表。我不认为这种方法非常漂亮,但它确实有效。避免丑陋的步骤5和6的另一种方法是for循环。
fname lines
1 f1.foo line_1_f1
2 f1.foo line_2_f1
3 f2.foo line_1_f2
4 f2.foo line_2_f2
5 f2.foo line_3_f2
两种情况下的输出都是
BEGIN()