在 r 循环中将多个 csv 文件组合在一起
Combining multiple csv files together in an r loop
我有一个文件夹,里面有很多 csv 文件。它们都是按图片结构
我有兴趣计算变量“Type”下的数字,并得到一个输出,告诉我有两个数字 7、两个数字 9、两个 1 等等。我想为我的文件夹中的 csv 文件执行此操作,将不同文件的输出绑定在一起会很好(带有一个标识符到从中提取输出的原始文件)。
到目前为止,我设法使用以下代码对单个文件执行此操作:
mydata <- read.csv("1_data.csv", skip=1, header = T)
df <- data.frame(table(mydata$Type))
但是,我尝试编写一个循环并卡住了。这是我使用的代码:
files = list.files(pattern = "*.csv")
for (i in files) {
id <- substr(i, 1, 5)
mydata <- read.csv (i, skip=1, header = T)
datatobind <- data.frame(table(mydata$Type))
datatobind["id"] <- as.numeric(id)
data <- rbind(data, datatobind)
}
do.call (rbind, data)
write.csv(data, file='final.csv', row.names=FALSE)
我每次尝试更改代码时都会遇到不同的错误,所以我不确定如何解决这个问题。
这里有几种方法可以从每个文件中计算 Type
列,使用文件名添加一个新列并将输出绑定在一起。
使用基础 R :
files = list.files(pattern = "*.csv", full.names = TRUE)
new_data <- do.call(rbind, lapply(files, function(x) {
mydata <- read.csv(x, skip=1, header = TRUE)
transform(as.data.frame(table(mydata$Type)),
filename = basename(x))
}))
和 tidyverse
:
library(dplyr)
new_data <- purrr::map_df(files, function(x) {
mydata <- read.csv(x, skip=1, header = TRUE)
mydata %>%
count(Type) %>%
mutate(filename = basename(x))
})
这是适合您需要的平行版本。
您可能需要安装 doSNOW 和 parallel 软件包:
library(doSNOW)
library(parallel)
setwd("path/to/folder")
all_files = list.files(pattern = "\.csv$")
num_files = length(all_files)
cl <- makeCluster(min(num_files, floor(detectCores()*0.9)), outfile = "")
registerDoSNOW(cl)
dataset <- foreach(i=1:num_files, .combine='rbind') %dopar%
{
read.csv(all_files[i], header=TRUE)
}
stopCluster(cl)
registerDoSEQ()
write.csv(dataset, file='final.csv', row.names=FALSE)
在 Windows 10 x64 上测试,与常规循环相比具有巨大的加速。
我有一个文件夹,里面有很多 csv 文件。它们都是按图片结构
我有兴趣计算变量“Type”下的数字,并得到一个输出,告诉我有两个数字 7、两个数字 9、两个 1 等等。我想为我的文件夹中的 csv 文件执行此操作,将不同文件的输出绑定在一起会很好(带有一个标识符到从中提取输出的原始文件)。 到目前为止,我设法使用以下代码对单个文件执行此操作:
mydata <- read.csv("1_data.csv", skip=1, header = T)
df <- data.frame(table(mydata$Type))
但是,我尝试编写一个循环并卡住了。这是我使用的代码:
files = list.files(pattern = "*.csv")
for (i in files) {
id <- substr(i, 1, 5)
mydata <- read.csv (i, skip=1, header = T)
datatobind <- data.frame(table(mydata$Type))
datatobind["id"] <- as.numeric(id)
data <- rbind(data, datatobind)
}
do.call (rbind, data)
write.csv(data, file='final.csv', row.names=FALSE)
我每次尝试更改代码时都会遇到不同的错误,所以我不确定如何解决这个问题。
这里有几种方法可以从每个文件中计算 Type
列,使用文件名添加一个新列并将输出绑定在一起。
使用基础 R :
files = list.files(pattern = "*.csv", full.names = TRUE)
new_data <- do.call(rbind, lapply(files, function(x) {
mydata <- read.csv(x, skip=1, header = TRUE)
transform(as.data.frame(table(mydata$Type)),
filename = basename(x))
}))
和 tidyverse
:
library(dplyr)
new_data <- purrr::map_df(files, function(x) {
mydata <- read.csv(x, skip=1, header = TRUE)
mydata %>%
count(Type) %>%
mutate(filename = basename(x))
})
这是适合您需要的平行版本。 您可能需要安装 doSNOW 和 parallel 软件包:
library(doSNOW)
library(parallel)
setwd("path/to/folder")
all_files = list.files(pattern = "\.csv$")
num_files = length(all_files)
cl <- makeCluster(min(num_files, floor(detectCores()*0.9)), outfile = "")
registerDoSNOW(cl)
dataset <- foreach(i=1:num_files, .combine='rbind') %dopar%
{
read.csv(all_files[i], header=TRUE)
}
stopCluster(cl)
registerDoSEQ()
write.csv(dataset, file='final.csv', row.names=FALSE)
在 Windows 10 x64 上测试,与常规循环相比具有巨大的加速。