在 R 中循环读取许多文件
Posted
技术标签:
【中文标题】在 R 中循环读取许多文件【英文标题】:Loop in R to read many files 【发布时间】:2011-08-11 02:43:56 【问题描述】:我一直想知道是否有人知道一种方法来创建在 R 中加载文件/数据库的循环。 假设我有一些这样的文件:data1.csv、data2.csv、...、data100.csv。
在某些编程语言中,您可以执行类似 data + x + .csv 的操作,系统会像 datax.csv 一样识别它,然后您可以应用循环。
有什么想法吗?
【问题讨论】:
这非常接近Loading many files at once。您只是在加载不同类型的文件。 【参考方案1】:Sys.glob()
是另一种可能性 - 它的唯一目的是通配符或通配符扩展。
dataFiles <- lapply(Sys.glob("data*.csv"), read.csv)
这会将data[x].csv
形式的所有文件读入列表dataFiles
,其中[x]
什么都不是。
[请注意,这与@Joshua 的答案中的模式不同。在那里,list.files()
采用正则表达式,而 Sys.glob()
只使用标准通配符;可以使用哪些通配符取决于系统,可以在帮助页面?Sys.glob
上找到详细信息。]
【讨论】:
是否有可能在结果列表中的每个项目都以通配符捕获的位命名?所以给定"folder\*.csv"
,每个列表项都将被称为data1
、data2
等。我意识到下面的循环之一可以工作(也许是assign()
?)但非循环解决方案感觉更优雅。【参考方案2】:
见?list.files
。
myFiles <- list.files(pattern="data.*csv")
然后你可以循环myFiles
。
【讨论】:
我假设您的意思是 pattern="data*.csv" ...但是看看 Gavin 的建议是否对我有帮助。是的,它确实......“。”是正则表达式中的通配符。 @DWin:我的意思是匹配单个字符零次或多次。 使用“data.*\\.csv”可能更安全? @DWin:我不确定这样会更安全。我的.*
会在文件扩展名之前捕获.
。如果你真的想要安全/明确,你可以使用"^data[[:digit:]]*\\.csv$"
。 :-)
我的想法是“data.*csv”不需要“。”在那里。【参考方案3】:
我会将所有 CSV 文件放在一个目录中,创建一个列表并执行循环以从列表中的目录中读取所有 csv 文件。
setwd("~/Documents/")
ldf <- list() # creates a list
listcsv <- dir(pattern = "*.csv") # creates the list of all the csv files in the directory
for (k in 1:length(listcsv))
ldf[[k]] <- read.csv(listcsv[k])
str(ldf[[1]])
【讨论】:
【参考方案4】:读取文件中的标题,以便我们可以将它们用于合并文件中的替换
library(dplyr)
library(readr)
list_file <- list.files(pattern = "*.csv") %>%
lapply(read.csv, stringsAsFactors=F) %>%
bind_rows
【讨论】:
【参考方案5】:fi <- list.files(directory_path,full.names=T)
dat <- lapply(fi,read.csv)
dat 将包含列表中的数据集
【讨论】:
这将列出directory_path
中的所有 个文件,这不是必需的。根据@Joshua 的回答,您需要pattern
。【参考方案6】:
假设您的文件具有您在问题中提到的文件格式,并且它们位于工作目录中。
如果文件名具有简单的命名结构,您可以矢量化创建文件名。然后对所有文件应用加载函数(这里我使用purrr包,但你也可以使用lapply
)
library(purrr)
c(1:100) %>% paste0("data", ., ".csv") %>% map(read.csv)
【讨论】:
我一直在使用类似的代码块来读取多个 .csv 文件,但是有没有办法将参数传递给 map 中的 read.csv 函数?具体来说,我想通过strings_as_factors = F
。如果不创建我自己的自定义 read.csv 函数,这可能吗?
是的,它只是返回一个警告说有一个未使用的参数。【参考方案7】:
这是另一个使用 for 循环的解决方案。我比其他人更喜欢它,因为它的灵活性以及所有 dfs 都直接存储在全局环境中。
假设您已经设置了工作目录,算法将迭代读取所有文件并将它们存储在名为“datai”的全局环境中。
list <- c(1:100)
for (i in list)
filename <- paste0("data", i)
wd <- paste0("data", i, ".csv")
assign(filename, read.csv(wd))
【讨论】:
【参考方案8】:如果您有心理学/运动/医学等领域的参与者数据集,这可能会有所帮助。
setwd("C:/yourpath")
temp <- list.files(pattern = "*.sav")
#Maybe you want to unselect /delete IDs
DEL <- grep('ID(04|08|11|13|19).sav', temp)
temp2 <- temp[-DEL]
#Make a list of that contains all data
read.all <- lapply(temp2, read_sav)
#View(read.all[1])
#Option 1: put one under the next
df <- do.call("rbind", read.all)
Option 2: make something within each dataset (single IDs) e.g. get the mean of certain parts of each participant
mw_extraktion <- function(data_raw)
data_raw <- data.frame(data_raw)
#you may now calculate e.g. the mean for a certain variable for each ID
ID <- data_raw$ID[1]
data_OneID <- c(ID, Var2, Var3) #put your new variables (e.g. Means) here
#end of function
data_combined <- t(data.frame(sapply(read.all, mw_extraktion) ) )
【讨论】:
【参考方案9】:-
首先,设置工作目录。
查找并存储所有以
.csv
结尾的文件。
逐行绑定它们。
以下是代码示例:
setwd("C:/yourpath")
temp <- list.files(pattern = "*.csv")
allData <- do.call("rbind",lapply(Sys.glob(temp), read.csv))
【讨论】:
以上是关于在 R 中循环读取许多文件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 for 循环在 Matlab 中读取许多声音文件?