2012-12-27 7 views
5

Napisałem następujący kod R, który identyfikuje duplikaty plików w katalogu. Jak można wektoryzować pętlę for za pomocą pakietu plyr (lub podobnego)? Chciałbym osiągnąć bardziej idiomatyczne rozwiązanie R niż to, które wymyśliłem.Jak wektoryzacji tego kodu R Korzystanie z Plyr, Apply lub podobne?

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 

wyjście jest (za pomocą małego katalog test):

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

Próbowałem:

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

ale skończyło się z unikalnym rzędzie dla każdej pary wartości klucza (MD5 , Nazwa pliku). Nie byłem w stanie uzyskać pożądanej mocy kompaktowej.

(Tło: W ramach ćwiczenia skonwertowałem kod Pythona przedstawiony przez Raymonda Hettingera w jego hicie PyCon AU 2011 "What Makes Python Awesome" .Zjedzenia są tutaj: http://slidesha.re/WKkh9M. Byłem w stanie przeciąć LOC na pół, ale myślę, że mogę zrobić lepiej - i dowiedzieć się więcej - przez wektoryzację).

+2

albo podążać za polecenie '' ldply' ze split (h, h $ Digest) '? –

+1

Arun and Ben - moim celem jest posiadanie listy, której kluczami są skróty md5, a wartości są listami nazw plików odpowiadających każdemu unikatowemu kluczowi (patrz przykładowe wyjście). Po uruchomieniu ldply (seq_along (filelist), function (idx) c (digest (filelist [idx], file = TRUE, algo = "md5"), filelist [idx])) wyniki są duplikowane klucze md5 i skojarzona nazwa pliku wartości. Próbowałem potykać się przez stopienie i odlewać bezskutecznie. – goplayer

Odpowiedz

6

Oto rozwiązanie w podstawie, która jest trochę bardziej zwięzły:

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

dziękuję za zwięzłe rozwiązanie. – goplayer

4

Oto jedna odpowiedź. Najpierw pobierz md5 i nazwy plików do data.frame z ldply. Następnie utwórz listę, którą chcesz, podając 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

Dzięki. To ma sens. – goplayer

Powiązane problemy