我有很多CSV,每个都对应一天的数据,存储方式如下:
Day1.csv:
ID, height, weight, color
a1, 3, 45, blue
a2, 3, 44, green
a3, 4, 48, blue
Day 2.csv:
ID, height, weight, color
a1, 4, 47, green
a2, 4, 44, green
a3, 5, 49, yellow
我想为每个功能(即身高,体重等)制作一个单独的数据框,其中包含来自每个csv的信息。每个功能的输出都如下所示:
height.df:
ID, Day1, Day2
a1, 3, 4
a2, 3, 4
a3, 3, 5
我曾尝试使用merge(),但这要求我一次只输入两列。我也不确定如何使用文件名来标记列。
答案 0 :(得分:4)
我会考虑将所有数据放入列表并将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]])))
从那里,你可以很容易地进行转换。例如,将整个数据集组成一个&#34;宽的&#34;数据集:
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
答案 1 :(得分:1)
如果你真的想制作单独的数据框,可以采用以下方法:
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
答案 2 :(得分:0)
这似乎适用于两个数据帧。
file_names <- list.files('C:/mydirectory/mycsvs', full.names = T)
file_list <- lapply(file_names, read.csv, stringsAsFactors = F)
所以把你的csv放在一个目录中,把它们读成一个列表。
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的记录。
如果有人想要摆脱这些循环,我很乐意听到它,特别是对于那个加入步骤。根据数据的大小,这可能会相对缓慢。
无论如何,您最终得到一个数据帧列表,其中列表元素的名称是该功能。根据您拥有的数据量,此列表可能会非常大。