2013-10-11 24 views
4

我有一組帶有重複條目的csv文件,我需要刪除並重寫相同名稱和格式的文件。閱讀文件列表,應用功能並用相同的名稱重寫

這是我迄今所做的,

filenames<-list.files(pattern =".csv") 
datalist <-lapply(filenames, function(x){read.csv(file=x,header=F)}) 
unique.list <- lapply(datalist,unique) 

而且我卡與列表中分離數據幀,並用相同的名字重寫。還有一個類似的問題,我嘗試了幾個小時,但無法理解程序。

+1

「體驗之聲」說確保你首先創建一個包含文件的目錄副本,並保留一份作爲神聖的原始文件。只是說。 –

回答

2

一種方法是使用mapply

mapply(function(filename, data) write.csv(data, file=filename), 
     filenames, 
     unique.list) 

要注意的是,如果你不修改filenames,這將覆蓋原始數據文件。

mapply默認會返回一個空列表。當你只使用功能的副作用,你可以用它裏面invisible如果你喜歡:

invisible(mapply(function(filename, data) write.csv(data, file=filename), 
      filenames, 
      unique.list)) 
3

如果不能馬上進行測試,這裏是做內所有需要的東西的方法lapply循環。修改後的數據將作爲列表返回並存儲在名爲datalist的變量中。

filenames <- list.files(pattern =".csv") 

datalist <- lapply(filenames, function(x) { 
    # Import data 
    tmp <- read.csv(file = x, header = F) 

    # Remove duplicated entries 
    if (any(duplicated(tmp))) 
    tmp <- tmp[-which(duplicated(tmp)), ] 

    # Write output 
    write.csv(tmp, x) 

    # Return revised data 
    return(tmp) 
}) 
4

我肯定會使用for循環。 Shhhhhh,不要告訴我說過的任何人。爲什麼?原因三...

  1. 你要調用write.csv爲它的副作用,不是的返回值,即你想有一個文件被寫入磁盤。當你想從你的函數返回值時使用*apply
  2. 主要瓶頸將是磁盤I/O,所以我期望使用for循環的性能開銷與使用*apply循環相比沒有性能開銷。
  3. *apply函數將在循環的每次迭代中吞噬內存,並且不保證在所有迭代完成之前釋放內存。在for循環中,如果覆蓋循環內的對象,則在下一次迭代開始時釋放內存。如果你正在處理大csv文件,這可能是一個優勢。我會嘗試找到一個答案的鏈接,其中for解決了lapply由於內存問題而無法解決的問題。

因此,所有你需要爲我的解決辦法,因爲你去重後的數據列表...

for(i in 1:length(filenames)){ 
    write.csv(unique.list[[i]] , filenames[[i]]) 
} 

Here is an answer是在需要可for循環,因爲lapply相當於跑進內存分配錯誤。

+0

哈哈,單獨關於'for'循環的附註值得+1 ;-)好的論證! – fdetsch

+1

@flowla lol我有時會認爲'for'循環遭到誹謗。他們有(我相信)他們是正確*解決方案的具體用例。 –

相關問題