2012-01-12 41 views
6

Trong khi R của ifelse là vô cùng tiện dụng, nó có một nhược điểm cụ thể: trong cuộc gọi ifelse(test, yes, no) tất cả các yếu tố của yesno được đánh giá, ngay cả những người đó sẽ được bỏ đi. Điều này là khá lãng phí nếu bạn đang sử dụng nó ở giữa một bài tập số phức tạp, nói trong một chức năng sẽ được cấp cho integrate, uniroot, optim hoặc bất cứ điều gì. Ví dụ, người ta có thể cóLooking for a ifelse hiệu quả hơn()

ifelse(test, f(x, y, z), g(a, b, c)) 

nơi fg là tùy tiện chức năng phức tạp hoặc chậm, có thể liên quan đến lồng nhau hơn ifelse 's.

Có ai đã viết thay thế cho ifelse chỉ đánh giá các thành phần của yes/no sẽ được giữ lại không? Về cơ bản, điều gì đó dọc theo các dòng của

out <- test 
for(i in seq_along(out)) 
{ 
    if(test[i]) out[i] <- f(x[i], y[i], z[i]) 
    else out[i] <- g(a[i], b[i], c[i]) 
} 

nhưng không có sự vụng về/không hiệu quả của vòng lặp rõ ràng. Điều này thậm chí có thể mà không đi vào bên trong của R?

+1

Tôi đoán tôi * có thể * sử dụng vòng lặp rõ ràng, nhưng sau đó tôi cảm thấy rằng tôi sẽ theo dõi câu nói cũ rằng một lập trình viên được xác định có thể viết Fortran bằng bất kỳ ngôn ngữ nào .... –

+1

thì ifelse() được đánh giá cho mỗi phần tử, và tương tự như 'có' và 'không chỉ được đánh giá cho các yếu tố liên quan, trừ khi hiểu biết của tôi về áp dụng là sai, nhưng tôi chắc chắn rằng nó đã làm việc cho tôi trong quá khứ – nzcoops

+0

I thử dùng 'mapply' với if() - else, và chậm hơn 10 lần so với' ifelse'! –

Trả lời

6

Tôi không nghĩ rằng vấn đề là ifelse. fg chỉ được đánh giá một lần trong biểu thức của bạn. Tôi nghĩ rằng vấn đề của bạn là fg chậm với vectơ.

Bạn có thể thay đổi các cuộc gọi thành fg để chúng chỉ được đánh giá trên một tập hợp con của vectơ.

out <- numeric(length(test)) #or whatever the output type is 
out[test] <- f(x[test], y[test], z[test]) 
out[!test] <- g(x[!test], y[!test], z[!test]) 

Bạn cần điều chỉnh điều này nếu có bất kỳ thành phần nào của testNA.

+0

Có, tôi đã làm điều này là tốt, nhưng nó khá cồng kềnh. –

+4

Nếu 'f' và' g' là ở tất cả các vectorised, thì đây là lựa chọn tốt nhất của bạn. Nếu không thì bất kỳ loại vòng lặp nào cũng sẽ làm. Và nếu bạn nghĩ rằng đó là mã xấu (đủ công bằng) thì bạn luôn có thể bọc nó trong một hàm và ẩn nó trong một tệp mà bạn không thường xuyên nhìn vào. –

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