根据您的评论,我们可以堆叠每个文件,然后将生成的数据帧从“长”格式转换为“宽”格式:
library(dplyr)
library(readr)
library(reshape2)
df = lapply(file_list, function(file) {
dat = read_csv(file)
dat$source.file = file
return(dat)
})
df = bind_rows(df)
df = dcast(df, id + name ~ source.file, value.var="value")
在上面的代码中,在读入每个文件后,我们添加了一个包含文件名(或其修改版本)的新列source.file。* 然后我们使用dcast 将数据帧从“long”转换为“宽”格式以从每个文件中为value 创建一个单独的列,每个新列采用我们刚刚在source.file 中创建的名称之一。
另请注意,根据您打算如何处理此数据框,您可能会发现将其保留为长格式(即跳过dcast 步骤)以进行进一步分析更方便。
附录:处理Aggregation function missing: defaulting to length 警告。当您有不止一行具有相同的id、name 和source.file 时,就会发生这种情况。这意味着有多个values 必须映射到同一个单元格,从而导致聚合。默认聚合函数是length(即该单元格中值的计数)。我所知道的唯一解决方法是 (a) 以长格式保存数据,(b) 使用不同的聚合函数(例如,mean),或者 (c) 添加额外的 counter 列来区分大小写id、name 和 source.file 的相同组合具有多个值。我们在下面演示这些。
首先,让我们创建一些假数据:
df = data.frame(id=rep(1:2,2),
name=rep(c("A","B"), 2),
source.file=rep(c("001","002"), each=2),
value=11:14)
df
id name source.file value
1 1 A 001 11
2 2 B 001 12
3 1 A 002 13
4 2 B 002 14
-
id、name 和 source.file 的每个组合只有一个值,因此 dcast 可以正常工作。
dcast(df, id + name ~ source.file, value.var="value")
id name 001 002
1 1 A 11 13
2 2 B 12 14
-
添加具有相同id、name 和source.file 的附加行。由于现在有两个values 被映射到一个单元格,dcast 必须聚合。默认的聚合函数是提供值的计数。
df = rbind(df, data.frame(id=1, name="A", source.file="002", value=50))
dcast(df, id + name ~ source.file, value.var="value")
Aggregation function missing: defaulting to length
id name 001 002
1 1 A 1 2
2 2 B 1 1
-
改为使用mean 作为聚合函数。
dcast(df, id + name ~ source.file, value.var="value", fun.aggregate=mean)
id name 001 002
1 1 A 11 31.5
2 2 B 12 14.0
-
添加一个新的counter 列以区分多行具有相同id、name 和source.file 的情况,并将其包含在dcast 中。这使我们回到每个单元格的单个值,但代价是某些source.files 有多个列。
# Add counter column
df = df %>% group_by(id, name, source.file) %>%
mutate(counter=1:n())
如您所见,counter 的值仅在 id、name 和 source.file 的一种组合的情况下具有值 1,但在一种情况下具有值 1 和 2其中有两行具有相同的 id、name 和 source.file(下面的第 3 行和第 5 行)。
df
id name source.file value counter
1 1 A 001 11 1
2 2 B 001 12 1
3 1 A 002 13 1
4 2 B 002 14 1
5 1 A 002 50 2
现在我们将dcast 包含在counter 中,因此我们得到两列source.file“002”。
dcast(df, id + name ~ source.file + counter, value.var="value")
id name 001_1 002_1 002_2
1 1 A 11 13 50
2 2 B 12 14 NA
* 我不确定你的文件名是什么样的,所以你可能需要调整它,创建一个具有唯一文件标识符的命名格式。例如,如果您的文件名遵循“file001.csv”、“file002.csv”等模式,您可以这样做:dat$source.file = paste0("Value", gsub("file([0-9]{3})\\.csv", "\\1", file)。