2012-12-27 25 views
5

Tôi đã viết mã R sau để xác định các tệp trùng lặp trong một thư mục. Làm thế nào có thể một vectorize for-loop bằng cách sử dụng gói plyr (hoặc tương tự)? Tôi muốn đạt được một giải pháp R thành ngữ hơn là một giải pháp tôi đã đưa ra.Làm thế nào để Vector hóa mã R này bằng cách sử dụng Plyr, Apply, hoặc tương tự?

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 

đầu ra là (sử dụng một thư mục thử nghiệm nhỏ):

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

tôi đã cố gắng:

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

nhưng đã kết thúc với một hàng duy nhất cho mỗi cặp giá trị quan trọng của (MD5 , tên tệp). Tôi đã không thể có được sản lượng nhỏ gọn mong muốn.

(Bối cảnh: Là bài tập, tôi đã chuyển đổi mã python do Raymond Hettinger trình bày trong bài phát biểu PyCon AU 2011 của mình "Điều gì tạo nên sự tuyệt vời của Python". Các trang trình bày ở đây: http://slidesha.re/WKkh9M. Tôi có thể cắt LOC một nửa, nhưng tôi nghĩ tôi có thể làm tốt hơn - và tìm hiểu thêm - bằng cách vectơ hóa).

+2

Hoặc làm theo 'lệnh ldply' của bạn với 'chia (h, h $ digest)'? –

+1

Arun và Ben - mục tiêu của tôi là có danh sách có khóa là băm md5 và giá trị là danh sách tên tệp tương ứng với mỗi khóa duy nhất (xem đầu ra mẫu). Khi tôi chạy ldply (seq_along (filelist), hàm (idx) c (digest (filelist [idx], file = TRUE, algo = "md5"), filelist [idx])) kết quả là các khóa md5 trùng lặp và tên tệp được liên kết giá trị. Tôi đã cố gắng vấp ngã vì tan chảy và bỏ đi vô ích. – goplayer

Trả lời

6

Dưới đây là một giải pháp trong cơ sở đó là ngắn gọn hơn một chút:

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

cảm ơn bạn vì giải pháp súc tích. – goplayer

4

Đây là một câu trả lời. Trước tiên, hãy lấy tên md5 và tệp trên một data.frame với ldply. Sau đó, tạo danh sách bạn muốn với 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

Cảm ơn. Điều đó có ý nghĩa. – goplayer

Các vấn đề liên quan