如何在R中读取多个文件并从中创建单个数据框?

时间:2016-09-26 22:46:00

标签: r rhdf5

目的

我在一个文件夹中有100个hdf5文件。对于可重现的示例,我们只考虑2个文件,即:

> list.files(pattern="*.hdf5")
[1] "Cars_20160601_01.hdf5" "Cars_20160601_02.hdf5"  

每个hdf5文件包含2个组dataframe。我想从data组中提取出2个对象。这些称为VDS_Veh_SpeedVDS_Chassis_CG_Position。同样,在frame组中有3个对象。只有对象frame与此组相关 我想阅读这些文件并提取上述相关变量。

我尝试了什么:

# Create a list all the hdf5 files
temp = list.files(pattern="*.hdf5")

# Read all files and create data frames from each using the file name as df name
for (i in unique(temp)){
  data <- h5read(file = i, name = "data") # ED data
  frame <- h5read(file = i, name = "frame") # Frame numbers
  ED <- data.frame(frames = frame$frame, 
                   speed.kph.ED = round(data$VDS_Veh_Speed*1.46667*0.3048*3.6,2),
                   pedal_pos = data$CFS_Accelerator_Pedal_Position)#fps

  df <- h5read(file = i, name = "data/VDS_Chassis_CG_Position")
  df <- as.data.frame(df)
  colnames(df) <- c("y", "x", "z")
  df$speed <- ED$speed.kph.ED 
  df$pedal_pos <- ED$pedal_pos
  df$file.ID <- i
  assign(i, df)
}  

现在,因为我拥有全局环境中的所有文件,所以我删除了额外的对象,只保留了新的dfs:

# Remove extra objects
rm(data, df, ED, frame, i, temp)

最后,我在环境中列出了dfs,然后创建了一个数据框:

DF_obj <- lapply(ls(), get)
fdc <- do.call("rbind", DF_obj)   

这对我有用。但是,正如评论中所提到的,应该避免使用assign。此外,我必须手动使用rm(),否则此代码将无效。在这种情况下,有没有办法避免assign

如果您需要数据文件,请参阅上面提到的2的链接:https://1drv.ms/f/s!AsMFpkDhWcnw6g7StJp9dzZ-nCr4

1 个答案:

答案 0 :(得分:2)

答案与您的代码基本相同,但有一些小的改动。我们只使用列表并对列表的元素进行正常分配,而不是使用assign()在全局环境中创建数据框。这可以节省潜在的错误,命名冲突,并且不必担心大量的清理工作。

temp = list.files(pattern="*.hdf5")
df_list = list()  # initialize a list

# Read all files into a list of data frames
for (i in unique(temp)){
  data <- h5read(file = i, name = "data") # ED data
  frame <- h5read(file = i, name = "frame") # Frame numbers
  ED <- data.frame(frames = frame$frame, 
                   speed.kph.ED = round(data$VDS_Veh_Speed*1.46667*0.3048*3.6,2),
                   pedal_pos = data$CFS_Accelerator_Pedal_Position)#fps

  df <- h5read(file = i, name = "data/VDS_Chassis_CG_Position")
  df <- as.data.frame(df)
  colnames(df) <- c("y", "x", "z")
  df$speed <- ED$speed.kph.ED 
  df$pedal_pos <- ED$pedal_pos

  # assign to the list. We can take care of the id cols automatically
  df_list[[i]] <- df
} 

names(df) <- unique(temp)
fdc <- data.table::rbindlist(df_list, idcol = "file.ID")

使用data.table::rbindlist将比使用do.call(rbind)更快,它会根据列表的名称为我们处理ID列。

相关问题