R 如何将标识符列添加到现有文件的批处理中?

R 如何将标识符列添加到现有文件的批处理中?,r,csv,batch-processing,R,Csv,Batch Processing,我正在运行一个不断生成单个.csv文件的计算机模型。每个文件都有一个唯一的文件名,对应于地理位置和实验处理。每个文件包含相同的数据。我想把这些文件合并成一个数据框,可以在R中进行统计分析 问题是,单个文件不包含标识符来说明它们代表的位置或处理方式。无法使计算机模型添加此信息(!?!) 因此,我希望获取目录中的所有.csv文件,向基于文件名识别它们的各个文件添加列,并将它们合并到单个数据帧中。我已经摆弄for循环两天了,不知道怎么做 可复制示例的我的版本: 这里是假设文件 Site1.Treatm

我正在运行一个不断生成单个.csv文件的计算机模型。每个文件都有一个唯一的文件名,对应于地理位置和实验处理。每个文件包含相同的数据。我想把这些文件合并成一个数据框,可以在R中进行统计分析

问题是,单个文件不包含标识符来说明它们代表的位置或处理方式。无法使计算机模型添加此信息(!?!)

因此,我希望获取目录中的所有.csv文件,向基于文件名识别它们的各个文件添加列,并将它们合并到单个数据帧中。我已经摆弄for循环两天了,不知道怎么做

可复制示例的我的版本:

这里是假设文件

Site1.Treatment <- data.frame(Data1 = seq(1000,5000, length.out=10), Data2 = seq(10,30, length.out=10))
Site1.NoTreatment <- data.frame(Data1 = seq(2000,3000, length.out=10), Data2 = seq(10,30, length.out=10))

Site1.Treatment假设文件在工作目录中,我们使用
list.files()
列出文件,通过
lapply
循环将这些文件读入
列表
,使用
sub
提取前缀('Site1','Site2')、中间部分('Treatment','nottreatment'),使用
Map
在每个
列表中创建列“Site”和“Treatment”,然后使用
rbind
创建单个
数据框

files <- list.files()
lst <- lapply(files, read.csv, header=TRUE, stringsAsFactors=FALSE)
v1 <- sub('\\..*', '', files)
v2 <- sub('.*\\.(.*)\\.csv', '\\1', files)
d1 <- do.call(rbind, Map(cbind, lst, Site=v1, Treatment= v2))

files假设文件在工作目录中,我们使用
list.files()
列出文件,通过
lapply
循环将其读入
列表,使用
sub
提取前缀('Site1','Site2')、中间部分('Treatment','nottreatment'),使用
Map
在每个
列表中创建列“Site”和“Treatment”,然后使用
rbind
创建单个
数据框

files <- list.files()
lst <- lapply(files, read.csv, header=TRUE, stringsAsFactors=FALSE)
v1 <- sub('\\..*', '', files)
v2 <- sub('.*\\.(.*)\\.csv', '\\1', files)
d1 <- do.call(rbind, Map(cbind, lst, Site=v1, Treatment= v2))

文件按照您的示例创建一些文件,您可以执行以下操作:

# Write some files
Site1.Treatment   <- data.frame(Data1 = seq(1000,5000, length.out = 10),
                                Data2 = seq(10,30, length.out = 10))
Site1.NoTreatment <- data.frame(Data1 = seq(2000,3000, length.out = 10),
                                Data2 = seq(10,30, length.out = 10))

write.csv(Site1.Treatment, file = "Site1.Treatment.csv")
write.csv(Site1.NoTreatment, file = "Site1.NoTreatment.csv")

# Read and combine the data
files <- list.files(pattern = "*.csv")

do.call(rbind, lapply(files, function(x) data.frame(read.csv(x), filename = x)))
#编写一些文件

Site1.Treatment按照您的示例创建一些文件,您可以执行以下操作:

# Write some files
Site1.Treatment   <- data.frame(Data1 = seq(1000,5000, length.out = 10),
                                Data2 = seq(10,30, length.out = 10))
Site1.NoTreatment <- data.frame(Data1 = seq(2000,3000, length.out = 10),
                                Data2 = seq(10,30, length.out = 10))

write.csv(Site1.Treatment, file = "Site1.Treatment.csv")
write.csv(Site1.NoTreatment, file = "Site1.NoTreatment.csv")

# Read and combine the data
files <- list.files(pattern = "*.csv")

do.call(rbind, lapply(files, function(x) data.frame(read.csv(x), filename = x)))
#编写一些文件

Site1.Treatment那么,您在一个公共目录中有一组文件,其中包含公共数据元素

如果是这样,可以使用
库(plyr)
非常优雅地完成这项工作:

#示例数据:
write.csv(data.frame(x=rnorm(100),y=rnorm(100)),“f1.csv”,row.names=FALSE)
write.csv(data.frame(x=rnorm(100),y=rnorm(100)),“f2.csv”,row.names=FALSE)
write.csv(data.frame(x=rnorm(100),y=rnorm(100)),“f3.csv”,row.names=FALSE)
#将工作目录设置为包含所有文件的位置:
图书馆(plyr)
#创建一个包含所需文件名和文件ID的列表
#IE-“ID”应该是您选择的字符向量。

l2那么,您在一个公共目录中有一组文件,其中包含公共数据元素

如果是这样,可以使用
库(plyr)
非常优雅地完成这项工作:

#示例数据:
write.csv(data.frame(x=rnorm(100),y=rnorm(100)),“f1.csv”,row.names=FALSE)
write.csv(data.frame(x=rnorm(100),y=rnorm(100)),“f2.csv”,row.names=FALSE)
write.csv(data.frame(x=rnorm(100),y=rnorm(100)),“f3.csv”,row.names=FALSE)
#将工作目录设置为包含所有文件的位置:
图书馆(plyr)
#创建一个包含所需文件名和文件ID的列表
#IE-“ID”应该是您选择的字符向量。

l2文件名的模式是什么?我不清楚你在哪里发现了问题:机械的还是设计的。您可以识别一列分隔csv数据集,例如,
站点
,并在从csv读取数据集时将其添加到每个数据集。您可以在读取csv时轻松地从csv创建数据帧,然后添加列“所有dfs中的标准”,并为每个df添加特定值。这些是向量运算,因此不需要任何for循环。这就是你想要做的吗?文件名的模式是什么?我不清楚你在哪里发现问题:机械的还是设计的。您可以识别一列分隔csv数据集,例如,
站点
,并在从csv读取数据集时将其添加到每个数据集。您可以在读取csv时轻松地从csv创建数据帧,然后添加列“所有dfs中的标准”,并为每个df添加特定值。这些是向量运算,因此不需要任何for循环。这就是你想要做的吗?我不认为这是预期的输出。这实际上可以做我需要的,谢谢。虽然有两个单独的列—site和treatment—会更整洁。是的,这只会创建带有文件名的列,然后您可以使用正则表达式对其进行解析,并根据文件名的构造方式创建具有相关信息的其他列(参见Akrun示例)我不认为这是预期的输出。这实际上可以做我需要的,谢谢。虽然有两个单独的列-site和treatment-会更整洁。是的,这只会创建带有文件名的列,然后您可以使用正则表达式来解析它,并根据文件名的构造方式创建具有相关信息的其他列(参见Akrun示例)。实际上,是的。实际上,是的。
# Write some files
Site1.Treatment   <- data.frame(Data1 = seq(1000,5000, length.out = 10),
                                Data2 = seq(10,30, length.out = 10))
Site1.NoTreatment <- data.frame(Data1 = seq(2000,3000, length.out = 10),
                                Data2 = seq(10,30, length.out = 10))

write.csv(Site1.Treatment, file = "Site1.Treatment.csv")
write.csv(Site1.NoTreatment, file = "Site1.NoTreatment.csv")

# Read and combine the data
files <- list.files(pattern = "*.csv")

do.call(rbind, lapply(files, function(x) data.frame(read.csv(x), filename = x)))
# example data:
write.csv(data.frame(x= rnorm(100), y= rnorm(100)), "f1.csv", row.names= FALSE)
write.csv(data.frame(x= rnorm(100), y= rnorm(100)), "f2.csv", row.names= FALSE)
write.csv(data.frame(x= rnorm(100), y= rnorm(100)), "f3.csv", row.names= FALSE)

# with your working directory set as the location with all the files:

library(plyr)
# create a list with the file names and the file ids that you wish
# IE- "ids" should be character vector of your choosing.
l2 <- data.frame(fls= dir(), ids= 1:length(dir()))
l2$fls <- as.character(l2$fls)
l2 <- split(l2, l2$ids)

# read in your files and add the ID column
l_ply(.data= l2, .fun= function(l, ids) {
  x <- read.csv(l$fls, header= TRUE, stringsAsFactors = FALSE)
  x$id <- l$id
  write.csv(x, l$fls, row.names = FALSE, col.names = TRUE)
  })

# now read in, and bind your files which have the appended ID column.
x <- ldply(dir(), .fun= read.csv, header= TRUE, stringsAsFactors=FALSE)