如何在 R 中读取多个文件并从中创建单个数据框?
How to read multiple files and create a single data frame from them in R?
Objective
我在一个文件夹中有 100 个 hdf5 文件。对于可重现的示例,我们只考虑 2 个文件,即:
> list.files(pattern="*.hdf5")
[1] "Cars_20160601_01.hdf5" "Cars_20160601_02.hdf5"
每个 hdf5 文件包含 2 个组,data
和 frame
。我想从 data
组中提取 2 个对象。这些称为 VDS_Veh_Speed
和 VDS_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
吗?
如果需要数据文件,这里是link到上面提到的2:https://1drv.ms/f/s!AsMFpkDhWcnw6g7StJp9dzZ-nCr4
答案与您的代码基本相同,但有一些小改动。我们只使用一个列表并正常分配给列表的元素,而不是使用 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 列。
Objective
我在一个文件夹中有 100 个 hdf5 文件。对于可重现的示例,我们只考虑 2 个文件,即:
> list.files(pattern="*.hdf5")
[1] "Cars_20160601_01.hdf5" "Cars_20160601_02.hdf5"
每个 hdf5 文件包含 2 个组,data
和 frame
。我想从 data
组中提取 2 个对象。这些称为 VDS_Veh_Speed
和 VDS_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
吗?
如果需要数据文件,这里是link到上面提到的2:https://1drv.ms/f/s!AsMFpkDhWcnw6g7StJp9dzZ-nCr4
答案与您的代码基本相同,但有一些小改动。我们只使用一个列表并正常分配给列表的元素,而不是使用 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 列。