将许多 CSV 合并到不同的数据框中
Posted
技术标签:
【中文标题】将许多 CSV 合并到不同的数据框中【英文标题】:Merging many CSVs into different data frames 【发布时间】:2015-09-16 17:30:54 【问题描述】:我有很多 CSV,每个对应一天的数据,存储如下:
Day1.csv:
ID, height, weight, color
a1, 3, 45, blue
a2, 3, 44, green
a3, 4, 48, blue
第 2 天.csv:
ID, height, weight, color
a1, 4, 47, green
a2, 4, 44, green
a3, 5, 49, yellow
我想为每个特征(即身高、体重等)制作一个单独的数据框,其中包含来自每个 csv 的信息。每个特征的输出如下所示:
高度.df:
ID, Day1, Day2
a1, 3, 4
a2, 3, 4
a3, 3, 5
我曾尝试使用merge(),但这要求我一次只输入两列。我也不确定如何使用文件名来标记列。
【问题讨论】:
你卡在问题的哪一部分?读取多个 CSV 文件?读入后合并文件中的数据? 在读入文件后合并文件中的数据。如果我不清楚,请见谅 【参考方案1】:这似乎适用于两个数据框。
file_names <- list.files('C:/mydirectory/mycsvs', full.names = T)
file_list <- lapply(file_names, read.csv, stringsAsFactors = F)
所以把你的 csvs 放在一个目录中,把它们读入一个列表。
library(dplyr)
new_dataframes = list()
for(i in 2:ncol(dataframes[[1]]))
new_list <- list()
for(j in 1:length(file_list))
new_list[[j]] <- file_list[[j]][, c(1, i)]
joined_df <- new_list[[1]]
for(j in 2:length(new_list))
joined_df <- inner_join(joined_df, new_list[[j]], by = 'ID')
for(j in 2:ncol(joined_df))
colnames(joined_df)[j] <- paste0('day ', j - 1)
feature_name <- colnames(new_list[[1]])[2]
new_dataframes[[feature_name]] <- joined_df
new_dataframes
$height
ID day 1 day 2
1 a1 3 4
2 a2 3 4
3 a3 4 5
$weight
ID day 1 day 2
1 a1 45 47
2 a2 44 44
3 a3 48 49
$color
ID day 1 day 2
1 a1 blue green
2 a2 green green
3 a3 blue yellow
这假设您有连续的天数(例如,您从第 1 天到第 n 天没有丢失的天数。如果不是这种情况,那么从文件标题中提取日期并不难,假设它在标题中。这还假设每个数据帧在列数/列顺序方面或多或少相同。如果不是这种情况,这将行不通。它还会执行inner_join
,因此您只会获取记录具有匹配的 ID。
如果有人有摆脱这些循环的想法,我很想听听,尤其是对于那个 join 步骤。根据数据的大小,这可能会变得相对较慢。
无论如何,您最终会得到一个数据框列表,其中列表元素的名称就是特征。根据您拥有的数据量,此列表可能会变得非常大。
【讨论】:
【参考方案2】:我会考虑将所有数据放入一个列表中,然后rbind
将数据放在一起(如果列属于相同类型)。
例子:
## Assume you have read in files and saved them as `data.frame`s named
## "day1", "day2", and so on....
temp <- mget(ls(pattern = "day\\d+"))
long <- do.call(rbind, lapply(names(temp), function(x) cbind(Day = x, temp[[x]])))
从那里,您可以很容易地进行转换。例如,将整个数据集变成一个“宽”数据集:
reshape(long, direction = "wide", idvar = "ID", timevar = "Day")
# ID height.day1 weight.day1 color.day1 height.day2 weight.day2 color.day2
# 1 a1 3 45 blue 4 47 green
# 2 a2 3 44 green 4 44 green
# 3 a3 4 48 blue 5 49 yellow
或者,只是一个特定的变量:
library(data.table)
dcast.data.table(as.data.table(long), ID ~ Day, value.var = "height")
# ID day1 day2
# 1: a1 3 4
# 2: a2 3 4
# 3: a3 4 5
【讨论】:
【参考方案3】:如果您真的想制作单独的数据框,可以使用以下方法:
Day1.csv <- read.table(header=T, sep=",", text="
ID, height, weight, color
a1, 3, 45, blue
a2, 3, 44, green
a3, 4, 48, blue")
Day2.csv <- read.table(header=T, sep=",", text="
ID, height, weight, color
a1, 4, 47, green
a2, 4, 44, green
a3, 5, 49, yellow")
library(tidyr)
l <- mget(ls(pattern = "Day\\d+\\.csv"))
df <- do.call(rbind, lapply(seq(l), function(x) transform(l[[x]], Day = paste0("Day", gsub("\\D", "", names(l)[x])))))
df <- gather(df, variable, value, -ID, -Day)
list2env(
setNames(lapply(levels(df$variable), function(x)
spread(df[df$variable == x, -which(names(df) == "variable")], Day, value, fill = 0)
), paste0(levels(df$variable), ".df")), globalenv())
weight.df
# ID Day1 Day2
# 1 a1 45 47
# 2 a2 44 44
# 3 a3 48 49
height.df
# ID Day1 Day2
# 1 a1 3 4
# 2 a2 3 4
# 3 a3 4 5
color.df
# ID Day1 Day2
# 1 a1 blue green
# 2 a2 green green
# 3 a3 blue yellow
【讨论】:
以上是关于将许多 CSV 合并到不同的数据框中的主要内容,如果未能解决你的问题,请参考以下文章
将具有不同架构(列)的多个文件 (.csv) 合并/合并为单个文件 .csv - Azure 数据工厂
将来自不同文件夹的多个 csv 文件(相似名称)合并到一个 csv 中并逐行绑定它们 [关闭]