2012-08-15 26 views

Trả lời

24

Vòng lặp ở cấp R không phải là được vectorized. Một vòng lặp R sẽ được gọi cùng một mã R cho mỗi phần tử của một vectơ, sẽ không hiệu quả. Các hàm vectơ thường tham chiếu đến các hàm lấy một vector và hoạt động trên toàn bộ vectơ một cách hiệu quả. Cuối cùng điều này sẽ liên quan đến một số vòng lặp, nhưng khi vòng lặp đó đang được thực hiện bằng một ngôn ngữ cấp thấp như C, nó có thể rất hiệu quả và phù hợp với nhiệm vụ cụ thể.

Xem xét chức năng ngớ ngẩn này để thêm cặp các yếu tố của hai vectơ

sillyplus <- function(x, y) { 
    out <- numeric(length = length(x)) 
    for(i in seq_along(x)) { 
     out[i] <- x[i] + y[i] 
    } 
    out 
} 

Nó cho kết quả đúng

R> sillyplus(1:10, 1:10) 
[1] 2 4 6 8 10 12 14 16 18 20 

và được vectorised theo nghĩa là nó có thể hoạt động trên toàn bộ vectơ cùng một lúc , nhưng nó không phải là vectorised theo nghĩa mà tôi mô tả ở trên vì nó đặc biệt không hiệu quả. + được vector hóa ở mức C trong R vì vậy chúng tôi chỉ thực sự cần 1:10 + 1:10, không phải là vòng lặp rõ ràng trong R.

Cách thông thường để viết hàm vectơ là sử dụng các hàm R hiện có đã được vectơ hóa. Nếu bạn muốn bắt đầu từ đầu và điều bạn muốn làm với hàm không tồn tại dưới dạng hàm vectơ trong R (kỳ quặc, nhưng có thể) thì bạn sẽ cần phải làm cho bàn tay của bạn bị bẩn và ghi các đường ruột của hàm trong C và chuẩn bị một gói nhỏ trong R để gọi hàm C bạn đã viết với vectơ dữ liệu bạn muốn nó hoạt động. Có nhiều cách với các hàm như Vectorize() để vectoris giả cho các hàm R không được vectơ hóa.

C không phải là lựa chọn duy nhất ở đây, FORTRAN là một khả năng như là C++ và, nhờ Dirk Eddelbuettel & Romain Francois, sau này là dễ dàng hơn nhiều việc phải làm bây giờ với rcpp gói.

7

Một hàm vectơ sẽ trả về một vectơ có độ dài bằng một trong các đối số của nó. Nói chung, người ta có thể nhận được một hàm như vậy bằng cách sử dụng các kết hợp các hàm dựng sẵn như "+", cos hoặc exp cũng được vector hóa.

vecexpcos <- function(x) exp(cos(x)) 
vecexpcos((1:10)*pi) 
> vecexpcos((1:10)*pi) 
# [1] 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818 0.3678794 2.7182818 

Nếu bạn cần phải sử dụng một hàm phi vectorized như sum, bạn có thể cần phải gọi mapply hoặc Vectorize để có được hành vi mong muốn.

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