我在业余时间写了很多R,并试图通过尽可能多地使用TidyVerse来养成良好的习惯。其中很大一部分要求将所有已过期日志文件的目录读入R中进行处理。数据量很大,所以我不会在这里发布一个,只要您在工作目录或数据目录中有匹配的文件名"./accounts_20180217.csv“或”./符号_20180217.csv“,就不重要了。
示例文件内容是:
16 109=18A
175 109=1FN
10 109=ABP
6 109=ABW
787 109=ACI
226 109=ACL
163 109=AD
644 109=AGM
79 109=AGN
40 109=AIG
2 109=AJT
991 109=ALG
4 109=ALGR
14 109=AM1
17 109=AN1
34 109=AP1
136 109=APA
267 109=APJ
160 109=ARE
64 109=ARX
329 109=AS1我一直在使用以下内容来读取和分类文件数据:
library(tidyverse)
library(stringr)
all_data <- tibble(
filename = list.files(
"./", pattern = "^(accounts|symbols)_201[7-9][0-9]{2}[0-9]{2}\\.csv$"
, full.names = TRUE
)
) %>%
mutate(
date = str_extract(filename, "201[7-9][0-9]{4}")
, type = str_extract(filename, "(accounts|symbols)")
, data = map2(
filename
, date
, ~read.csv(
.x
, header = FALSE
, sep = "="
, as.is = TRUE
, col.names = c("count", "names")
, colClasses = c("integer", "character") ))
)我的问题是,这是一个好的和蒂迪的方式来实现这一点,还是有“更好”或“更整洁”的方式?
发布于 2018-09-12 23:30:25
我想,一致的tidyverse解决方案将使用readr::read_csv。
您不需要map2,如果不使用.y,map就足够了。
您可以使用read.csv作为您的.f参数,其余部分留给您的map调用中的...处理,这可能是一个有趣的问题,但我更喜欢这样做,因为您必须阅读公式符号,以确保read.csv是唯一被调用的函数。
如果您已经提供了列类,那么as.is似乎没有必要。
您的mutate调用是不必要的,tibble将懒洋洋地计算上一步给出的filename定义。
你似乎真的想要一条“一条线”,但在我看来,在几个步骤内会更清楚一些,我建议如下:
files <- list.files(
"./",
full.names = TRUE,
pattern = "^(accounts|symbols)_201[7-9][0-9]{4}\\.csv$")
data_lst <- map(
files,
read_csv,
header = FALSE,
sep = "=",
coltypes = "ic",
col_names = c("count", "names"))
tibble(
file_name = files,
date = str_extract(filename, "201[7-9][0-9]{4}"),
type = str_extract(filename, "(accounts|symbols)"),
data = data_lst)实际上,在处理大量数据文件时,我倾向于编写一个for循环,而不是一个map调用,这样,如果出现问题,我可以更容易地调试和继续操作,而无需重新启动所有这些文件。
https://codereview.stackexchange.com/questions/203614
复制相似问题