将许多CSV合并到不同的数据框中

时间:2015-06-30 04:16:06

标签: r csv merge dataframe

我有很多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(),但这要求我一次只输入两列。我也不确定如何使用文件名来标记列。

3 个答案:

答案 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的记录。

如果有人想要摆脱这些循环,我很乐意听到它,特别是对于那个加入步骤。根据数据的大小,这可能会相对缓慢。

无论如何,您最终得到一个数据帧列表,其中列表元素的名称是该功能。根据您拥有的数据量,此列表可能会非常大。