2012-12-27 9 views
5

Ich schrieb den folgenden R-Code, der doppelte Dateien in einem Verzeichnis identifiziert. Wie kann man die for-Schleife mit dem plyr-Paket (oder ähnlichem) vektorisieren? Ich möchte eine idiomatische R-Lösung erreichen, als die, die ich mir ausgedacht habe.Wie vektorisiert man diesen R-Code mit Plyr, Apply oder Ähnlichem?

library("digest") # to compute the MD5 digest 
test_dir = "/Users/user/Dropbox/kaggle/r_projects/test_photo" 
filelist <- dir(test_dir, pattern = "JPG|AVI", recursive=TRUE, 
       all.files =TRUE, full.names=TRUE) 

fl = list() #create and empty list to hold md5's and filenames 

for (itm in filelist) { 
    file_digest = digest(itm, file=TRUE, algo="md5") 
    fl[[file_digest]]= c(fl[[file_digest]],itm) 
} 
fl 

der Ausgang (ein kleines Test Verzeichnis verwenden):

> fl 
$`5715b719723c5111b3a38a6ff8b7ca56` 
[1] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_a/IMG_3480 copy.JPG" 
[2] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_a/IMG_3480.JPG"  

$`24fd4d7d252ca66c8d7a88b539c55112` 
[1] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_a/IMG_3481 copy.JPG" 
[2] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_a/IMG_3481.JPG"  
[3] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_b/IMG_3481.JPG"  

$`2a1d668c874dc856b9df0fbf3f2e81ec` 
[1] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_a/IMG_3482 copy.JPG" 
[2] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_a/IMG_3482.JPG"  
[3] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_b/IMG_3482 copy.JPG" 
[4] "/Users/user/Dropbox/kaggle/r_projects/test_photo/folder_b/IMG_3482.JPG"  

Ich habe versucht:

h=ldply(filelist, digest, file=TRUE, algo="md5") 
h$filenames=filelist 

aber mit einer einzigartigen Reihe für jeden Schlüsselwert Paar (MD5 endete , Dateiname). Ich konnte den gewünschten kompakten Ausgang nicht erreichen.

(Als Übung habe ich den Python Code von Raymond Hettinger in seinem PyCon AU 2011 Keynote "What Makes Python Awesome" konvertiert. Die Folien sind hier: http://slidesha.re/WKkh9M. Ich konnte das LOC in zwei Hälften schneiden, aber ich denke, ich kann es besser machen - und mehr lernen - durch Vektorisierung).

+2

Oder Ihrem 'ldply' Befehl folgt mit' Split (h, h $ digest) '? –

+1

Arun und Ben - mein Ziel ist es, eine Liste zu haben, deren Schlüssel die MD5-Hashes sind, und die Werte sind Listen von Dateinamen, die jedem eindeutigen Schlüssel entsprechen (siehe Beispielausgabe). Wenn ich ldply (seq_along (Dateiliste), Funktion (idx) c (Digest (Dateiliste [idx], Datei = TRUE, Algo = "md5", Dateiliste [idx])) die Ergebnisse sind doppelte MD5-Schlüssel und den zugehörigen Dateinamen Werte. Ich habe versucht, durch die Schmelze zu stolpern und ohne Erfolg zu wirken. – goplayer

Antwort

6

Hier ist eine Lösung in der Basis, die ein wenig mehr prägnant:

md5s<-sapply(filelist,digest,file=TRUE,algo="md5") 
split(filelist,md5s) 
+0

danke für die prägnante Lösung. – goplayer

4

Hier ist eine Antwort. Rufen Sie zuerst die MD5- und Dateinamen auf einem data.frame mit ldply. Erstellen Sie dann die gewünschte Liste mit dlply.

fl <- ldply(seq_along(filelist), function(idx) 
      c(digest(filelist[idx], file=TRUE, algo="md5"), 
      filelist[idx])) 
fl <- dlply(fl, .(V1), function(x) x$V2) 
+0

Danke. Das macht Sinn. – goplayer

Verwandte Themen