2017-10-06 46 views
0

我試圖通過多個CSV文件循環併爲每個文件完成相同的任務以節省自己的時間。首先,我運行'list.files'列出文件夾中的所有文件(例如,GPS_Collar33800_13.csv,GPS_Collar33801_13.CSV等)。然後,我開發了一個循環,但我正在努力構建代碼的其他部分來處理每個單獨的文件。我的最終目標是有24個文件在結構上看起來相同,然後我需要將它們合併到一個主文件中。另一個問題是,我需要爲每個文件列出一個唯一的ID(爲領領ID添加專欄,例如33800,33801,33802等),但我不知道如何輕鬆完成此操作,而無需手動添加新的獨特ID(如果我知道它首先引入文件GPS_Collar33800_13.csv,那麼我可以使AnimalID列值= 33800,併爲GPS_Collar33801_13.csv做同樣的事情並添加AnimalID列值= 33801)。唯一的ID是基於文件名。我們歡迎所有的建議!通過CSV文件循環 - 爲每個單獨文件發出完成任務

## List CSV files in folder 
`files<-list.files()` 

## Run a for loop to complete the same tasks for each 
for (i in 1:length(files)){ 
## Read table 
tmp<-read.table(files[i],header=FALSE,sep=" ") 
## Keep certain columns 
tmp1 <- tmp[c(2:5,9,10,12,13)] 
#Name the remaining columns 
names(tmp1) <- 
c("GMT_Date","GMT_Time","LMT_Date","LMT_Time","Latitude","Longitude","PDOP","2D_3D") 
#Add column for collar ID 
tmp1$AnimalID<-33800 
#Cleanup dataframe by removing records with NAs 
tmp1[tmp1 == "N/A"] <- NA 
tmp2<-na.omit(tmp1) 

回答

0

你可以試試這個:

library(stringr) 
## List CSV files in folder 
files<-list.files() 

big.df <- vector('list',length(files)) 

## Run a for loop to complete the same tasks for each 
for (i in 1:length(files)){ 
    ## Read table 
    tmp<-read.table(files[i],header=FALSE,sep=" ") 
    ## Keep certain columns 
    tmp1 <- tmp[c(2:5,9,10,12,13)] 
    #Name the remaining columns 
    names(tmp1) <- 
    c("GMT_Date","GMT_Time","LMT_Date","LMT_Time","Latitude","Longitude","PDOP","2D_3D") 
    #Add column for collar ID 
    tmp1$AnimalID<-str_match(files[i], 'Collar(\\d+)_')[,2] 
    #Cleanup dataframe by removing records with NAs 
    tmp1[tmp1 == "N/A"] <- NA 
    tmp2<-na.omit(tmp1) 
    big.df[[i]] <- tmp2 

} 
final.df <- do.call('rbind', big.df) 

這將需要stringr包,並假定您的文件名看起來都像「GPS_Collar33801_13.csv」,等等,那麼它在每個文件讀取,存儲它在一個大的列表中,移動到下一個文件......當它完成時,它們將它們全部混合在一個名爲final.df的數據框中。

編輯:剛剛修正str_match的說法。

+0

完美地工作!謝謝! – Buck2079

+0

@ Buck2079很高興能夠聽到它:)如果你願意接受答案,我將不勝感激......雖然我不是代表它的! (我是。) – Balter

0

因此,讓我確認之前,我開始,我明白問:

  1. 有關文件夾中的每個文件,
    1. 導入文件作爲數據幀
    2. 下降一些列
    3. 重命名其餘列
    4. 將數據框中的列設置爲從文件名
    5. 中獲得的值3210
    6. 刪除包含字符串「N/A」的任何地方
  2. 然後情況下,由每個所產生的數據幀組合到一個數據幀UNION-ING它們(即,添加的行一起因爲列應一樣)。

您提供任何此類問題的數據至關重要。如果您無法提供您的具體數據,請創建一些仍能證明問題即將出現的假數據。然後,舉例說明一旦操作完成後它應該是什麼樣子。這可以減少回答你問題的人的猜測。

因此,儘管如此,讓我們開始吧。

讓我們假設我們有一個函數process_a_file抽象出任務#1的子部分,它將執行每個單獨文件的步驟1-5並返回一個數據幀。我可以在後面解釋這個功能的作用。

對於「每個文件」部分,您需要lapplylapply運行提供列表中的每個元素在一個給定的功能,並返回該函數返回什麼的列表:

results_list <- lapply(files, process_a_file) 

這將返回一個列表,該列表中的每個元素是process_a_file返回的數據幀。然後,你需要一個功能,把它們混合起來 - 我建議bind_rows從包裝dplyr

results_df <- dplyr::bind_rows(results_list) 

而這一切,你需要做的!

那麼,現在,我們在process_a_file中放什麼?這是很容易 - 你的代碼是這樣做的主要是完整的,但也有一些不同的方式來做到這一點,我喜歡:)

process_a_file <- function(filename) { 
    #??????? 
} 

第1步是將文件導入的數據幀。爲此,我建議read_delimreadr包 - 它比默認的[R方法快得多,具有良好的默認值,讓我們通過指定「N/A」是指解決在同一時間第5步NA

df <- readr::read_delim(filename, delim = " ", col_names = FALSE, na = "N/A") 

對於第2步,用自己的方式工作,但我還建議從dplyrselect功能:

dplyr::select(df, 2:5,9,10,12,1) 

您還可以索引列與不帶引號的名稱,並與-5-column_name太刪除列 - 你可以做第3步與此同時!

df <- dplyr::select(
    df, 
    GMT_Date = 2, 
    GMT_Time = 3, 
    LMT_Date = 4, 
    LMT_Time = 5, 
    Latitude = 9, 
    Longitude = 10, 
    PDOP = 12, 
    `2D_3D` = 13 
) 

重命名列的方式也很好。順便說一句,如果你用一個數字開始一個列名,你必須在任何地方使用這個`backtick`語法,所以這很不方便,如果可以的話,你應該避免它。

最後,我建議使用正則表達式從文件名中獲取ID。我假設你可以編寫正則表達式,因爲這真的超出了範圍 - 所以你可以使用basename(tools::file_path_sans_ext(filename)返回沒有路徑或擴展名的文件名,並使用stringr::str_extract彈出ID,然後使用dplyr添加到列::變異

dplyr::mutate(df, animal_id = stringr::str_extract(basename(tools::file_path_sans_ext(filename)), "THE REGEX GOES HERE")) 

所以,現在,把這個一起 - 使用dplyr的管道語法%>%,以使它看起來不錯:

process_a_file <- function(filename) { 
    readr::read_delim(filename, 
        delim = " ", 
        col_names = FALSE, 
        na = "N/A") %>% 
    dplyr::select(
     GMT_Date = 2, 
     GMT_Time = 3, 
     LMT_Date = 4, 
     LMT_Time = 5, 
     Latitude = 9, 
     Longitude = 10, 
     PDOP = 12, 
     `2D_3D` = 13 
    ) %>% 
    dplyr::mutate(animal_id = stringr::str_extract(basename(tools::file_path_sans_ext(filename)), "THE REGEX GOES HERE")) 
} 
results_list <- lapply(files, process_a_file) 
results_df <- dplyr::bind_rows(results_list) 
相關問題