2016-09-26 16 views
0

目標

我在一個文件夾中有100個hdf5文件。對於重複的例子,讓我們只考慮2個文件,分別是:如何在R中讀取多個文件並從中創建單個數據幀?

> 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) 

This works fo我。但是,如評論中所述,應該避免使用assign。此外,我必須手動使用rm(),沒有這些代碼將無法工作。在這種情況下有什麼辦法可以避免assign

如果你需要的數據文件,這裏是鏈接到上面提到的2:https://1drv.ms/f/s!AsMFpkDhWcnw6g7StJp9dzZ-nCr4

+1

'fortunes :: fortune(236)' – alistaire

+0

@alistaire這是什麼意思? –

+0

這是[fortunes](https://cran.r-project.org/web/packages/fortunes/index.html)包中的一個引用,它暗示了'assign'是最好的避免。 – alistaire

回答

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列的我們。

+0

感謝您的回答。但是,這不起作用,因爲循環中的'i'是因爲使用'unique(temp)'而導致的文件名稱。所以,'df_list [[i]] < - df'會拋出錯誤。這是我嘗試使用'assign'的原因。 –

+0

爲什麼這不起作用?什麼錯誤? 'my_list = list(); my_list [[「item_one」]] = mtcars; my_list [[「your_filename.hdf5」]] = iris; i =「another_filename.hdf5」; my_list [[i]] < - data.frame(x = 1:2)'工作得很好。 – Gregor

+0

@umairdurrani您是否跳過'df_list = list()'行在循環前初始化列表? – Gregor

相關問題