使用ldply (包"plyr")从一个文件夹导入多个csv文件:标题信念,以及如何对多个文件夹进行导入?
设立:
我想从特定的文件夹中导入多个csv文件,并将它们合并为一个文件,其中包含5列: Variable1/Variable2/file_name/experiment_nb/pulse_nb我已经成功地从同一个data.frame中以前的类似问题中导入了来自同一个文件夹的所有文件,但是,我不知道如何对不同的文件夹和合并后的每个文件的头进行导入。由于文件太大,无法手动处理(每个文件有20万行),所以我希望确保没有任何错误会导致所有后续分析失败,例如导入每个csv文件的数据之前的头行。
csv看起来是这样的:"20190409-0001_002.csv“,后面跟着示例中的实验名称(0001)和脉冲数(002)。
#setting package and directory
library(plyr)
library(stringr)
setwd("/Users/macbook/Desktop/Project_Folder/File_folder1")
#Creating a list of all the filenames:
filenames <- list.files(path = "/Users/macbook/Desktop/Project_Folder/File_folder1")
#creating a function to read csv and in the same time adding an additional column with the name of the file
read_csv_filename <- function(filename)
{
ret <- read.csv(filename, header=TRUE, sep=",")
ret$Source <- filename #EDIT
ret
}
#importing
import <- ldply(filenames, read_csv_filename)
#making a copy of import
data<-import
#modifying the file name so it removes ".csv" and change the header
data$Source<-str_sub(data$Source, end=-5)
data[1,3]<-"date_expnb_pulsenb"
t<-substr(data[1,3],1,3)
head(data, n=10)
#create a column with the experiment number, extracted from the file name
data$expnb<-substr(data$Source, 10, 13)
data$expnb<-as.numeric(data$expnb)
head(data, n=10)
tail(data, n=10)1°现在我需要设法在相同的文件中导入所有其他文件夹,这最终可以手动完成,因为文件夹的数量是手动完成的(9-10),但是我正在考虑为将来的大量实验编写代码。怎么做?首先列出所有文件夹,然后列出这些文件夹中的所有文件,然后将它们重新分组到一个列表文件中?这对list.files是可行的吗?文件夹名如下所示:"20190409-0001“
以上代码(head(data,n=10))的结果如下所示:
> head(data, n=10)
Time Channel.A Source pulsenb expnb
1 (us) (A) expnb_pulsenb NA NA
2 -20.00200030 -0.29219970 20190409-0001_002 2 1
3 -20.00100030 -0.29219970 20190409-0001_002 2 1和
> tail(data, n=10)
Time Channel.A Source pulsenb expnb
20800511 179.99199405 -0.81815930 20190409-0001_105 105 1
20800512 179.99299405 -0.81815930 20190409-0001_105 105 1我想要对现在的大列表进行广泛的数据分析,我想知道如何检查它们中间没有带有文件头的行。作为csv文件中相同的头,ldply函数是否已经考虑到了报头?所有文件头会在“导入”数据帧中的一个单独行中吗?怎么检查呢?(不幸的是,每个文件中大约有200行XXX,所以我不能真正手动检查头)。
我希望我增加了所有所需的细节,并以正确的格式提出问题,因为这是我第一次在这里发帖:)
提前感谢你们的帮助!
发布于 2019-06-03 11:33:52
我也将使用purrr的map_dfr添加我的解决方案。
生成数据
这只会在临时目录中生成大量csv文件供我们操作。这是帮助我们回答问题的好方法。
library(tidyverse)
library(fs)
temp_directory <- tempdir()
library(nycflights13)
library(nycflights13)
purrr::iwalk(
split(flights, flights$carrier),
~ { str(.x$carrier[[1]]); vroom::vroom_write(.x, paste0(temp_directory,"/", glue::glue("flights_{.y}.csv")),
delim = ",") }
)自定义函数
看起来您有一个自定义函数来读取某些信息,因为文件的格式可能不同。这是我对你所做的事的攻击。
# List of files
my_files <- fs::dir_ls(temp_directory, glob = "*.csv")
custom_read_csv <- function(file){
# Read without colnames
ret <- read_csv(file, col_names = FALSE)
# Pull out column names
my_colnames <- unlist(ret[1,])
# Remove the row
ret <- ret[-1,]
# Assign the column names
colnames(ret) <- my_colnames
# Trick to remove the alpha in a row you know should be time
ret <- filter(ret, !is.na(as.numeric(T)))
}现在,您可以使用自定义函数读取所有文件,并使用map_dfr组合成一个单一的数据格式。
all_files <- map_dfr(my_files, custom_read_csv, .id = "filename")
head(all_files)看起来是这样的:
> head(all_files)
# A tibble: 6 x 20
filename year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight tailnum
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 C:/User~ 2013 1 1 810 810 0 1048 1037 11 9E 3538 N915XJ
2 C:/User~ 2013 1 1 1451 1500 -9 1634 1636 -2 9E 4105 N8444F
3 C:/User~ 2013 1 1 1452 1455 -3 1637 1639 -2 9E 3295 N920XJ
4 C:/User~ 2013 1 1 1454 1500 -6 1635 1636 -1 9E 3843 N8409N
5 C:/User~ 2013 1 1 1507 1515 -8 1651 1656 -5 9E 3792 N8631E您可以使用以下语法删除根路径(我的路径现在在那里):
all_files %>%
mutate(filename = str_remove(filename, "C:/Users/AppData/Local/Temp/RtmpkdmJCE/"))发布于 2019-06-03 11:13:47
我创建了一个文件夹和文件的假环境,假设您将逻辑地重新组合所有的文件和文件夹。
# ---
# set up folders and data
lapply( as.list(paste0("iris", 1:3)), dir.create )
iris_write <- function(name) write.csv(x = iris, file = name)
lapply( as.list(paste0("iris", 1:3, "/iris", 1:3, ".csv")), iris_write)
# Supposing you got them all in one folder, one level up
ldir <- list.dirs()
ldir <- ldir[stringr::str_detect(string = ldir, pattern = "iris")] # use 20190409-0001 in your case
# Getting all files
lfiles <- lapply( as.list(ldir), list.files )
# Getting all path
path_fun <- function(dirname) paste0(dirname, "/", list.files(dirname) )
lpath <- lapply( as.list(ldir), path_fun )使用r或/和包data.table
# ---
# --- Import, with functions that detect automatically headers, sep + are way faster to read data
# *** Using data.table
library(data.table)
read_csv_filename <- function(filename){
ret <- fread(filename)
ret$Source <- filename #EDIT
ret
}
ldata <- lapply( lpath , read_csv_filename )
# --- if you want to regroup them
# with r base
df_final <- do.call("rbind", ldata)
# using data.table
df_final <- rbindlist(ldata)使用包dplyr
# *** using dplyr
library(dplyr)
read_csv_filename2 <- function(filename){
ret <- reader(filename)
ret$Source <- filename #EDIT
ret
}
ldata <- lapply( lpath , read_csv_filename )
df_final <- bind_rows(ldata)
# you may do this with plyr::ldply also
df_final2 <- plyr::ldply(ldata, data.frame)
# *** END loading最后一个建议:来自包工具的file_path_sans_ext
# modifying the file name so it removes ".csv" and change the header
library(tools)
data$Source <- tools::file_path_sans_ext( data$Source )
#create a column with the experiment number, extracted from the file name
data$expnb <- substr(data$Source, 10, 13)
data$expnb <- as.numeric(data$expnb)希望有此帮助:)
https://stackoverflow.com/questions/56424205
复制相似问题