2015-07-21 28 views
9

Tôi đang sử dụng chức năng lapply trên danh sách nhiều tệp. Có cách nào mà tôi có thể bỏ qua các chức năng trên tập tin hiện tại mà không trả lại bất cứ điều gì và chỉ cần bỏ qua đến tập tin tiếp theo trong danh sách các tập tin?R: chức năng lapply - bỏ qua vòng lặp chức năng hiện tại

Để chính xác, tôi có câu lệnh if để kiểm tra điều kiện và tôi muốn chuyển sang tệp tiếp theo nếu câu lệnh trả về FALSE.

+1

Bạn có thể sử dụng điều kiện để chọn một tập hợp con của danh sách của bạn và lưu trữ tập hợp con này trong một biến riêng biệt mà bạn cung cấp cho 'lapply'. – RHertel

+0

@RHertel Vì chúng đang xử lý danh sách các tệp và không phải là một phần dữ liệu đã có trong RAM nên chúng không có thông tin để đặt trước các tệp. –

Trả lời

8

lapply sẽ luôn trả về một danh sách có độ dài bằng X nó được cung cấp. Bạn có thể chỉ cần đặt các mục vào thứ gì đó mà sau này bạn có thể lọc ra.

Ví dụ, nếu bạn có chức năng parsefile

parsefile <-function(x) { 
    if(x>=0) { 
    x 
    } else { 
    NULL 
    } 
} 

và bạn chạy nó trên một vector runif(10,-5,5)

result<-lapply(runif(10,-5,5), parsefiles) 

sau đó bạn sẽ có danh sách của bạn đầy những câu trả lời và NULL s

Bạn có thể đặt số NULL s bằng cách thực hiện ...

result[!vapply(result, is.null, logical(1))] 
+0

Bit cuối cùng có thể được cải thiện: 'list.condition <-! Vapply (kết quả, is.null, lôgic (1))'. Nếu không, một câu trả lời tuyệt vời. – sdgfsdh

+0

@sdgfsdh đẹp ... chỉnh sửa để phản ánh. –

+0

Đừng quên một '!' – sdgfsdh

0

Bạn có thể xác định chức năng tùy chỉnh để sử dụng trong cuộc gọi đến lapply(). Dưới đây là một số mẫu mã mà lặp trên một danh sách các tập tin và xử lý một tập tin duy nhất nếu tên không chứa số 3 (một chút giả tạo, nhưng hy vọng điều này được các điểm trên):

files <- as.list(c("file1.txt", "file2.txt", "file3.txt")) 

fun <- function(x) { 
    test <- grep("3", x)      // check for files with "3" in their name 
    if (length(test) == 0) {     // replace with your statement here 
     // process the file here 
    } 
    // otherwise do not process the file 
} 

result <- lapply(files, function(x) fun(x)) // call lapply with custom function 
2

Như đã được trả lời bởi những người khác, tôi không nghĩ rằng bạn có thể tiếp tục lặp lại tiếp theo mà không trả lại một cái gì đó bằng cách sử dụng các chức năng của *apply.

Trong trường hợp này, tôi sử dụng phương pháp Dean MacGregor, với một thay đổi nhỏ: Tôi sử dụng NA thay vì NULL, giúp lọc kết quả dễ dàng hơn.

files <- list("file1.txt", "file2.txt", "file3.txt") 

parse_file <- function(file) { 
    if(file.exists(file)) { 
    readLines(file) 
    } else { 
    NA 
    } 
} 

results <- lapply(files, parse_file) 
results <- results[!is.na(results)] 

Một điểm chuẩn nhanh

res_na <- list("a", NA, "c") 
res_null <- list("a", NULL, "c") 
microbenchmark::microbenchmark(
    na = res_na[!is.na(res_na)], 
    null = res_null[!vapply(res_null, is.null, logical(1))] 
) 

minh họa rằng giải pháp NA là nhanh hơn so với các giải pháp sử dụng NULL khá một chút:

Unit: nanoseconds 
expr min lq mean median uq max neval 
    na 0 1 410.78 446 447 5355 100 
null 3123 3570 5283.72 3570 4017 75861 100 
Các vấn đề liên quan