Tốc độ tính toán trong R?


16

Tôi đã được giao nhiệm vụ chuyển một trong những mô hình ngẫu nhiên lớn hiện tại của chúng tôi ra khỏi SAS và sang một ngôn ngữ mới. Cá nhân, tôi thích một ngôn ngữ được biên dịch truyền thống, nhưng PI muốn tôi kiểm tra R, thứ mà tôi chưa bao giờ sử dụng. Động lực của chúng tôi để đưa mô hình ra khỏi SAS là (1) nhiều người không có quyền truy cập vào mô hình này vì SAS đắt tiền, (2) chúng tôi đang tìm cách tránh xa một ngôn ngữ được dịch và (3) SAS chậm loại mô hình chúng ta có.

Đối với (1), rõ ràng R thỏa mãn nhu cầu cho nó là miễn phí. Đối với (2), lý tưởng nhất là chúng tôi muốn tạo một tệp thực thi, nhưng R thường được sử dụng làm ngôn ngữ theo kịch bản. Tôi thấy rằng gần đây ai đó đã đưa ra một trình biên dịch R - điều này có được đón nhận không? Nó có dễ sử dụng không? Chúng tôi thà không ép buộc người dùng tải xuống R. Đối với (3), vấn đề của chúng tôi với SAS là toàn bộ thời gian dành cho việc viết và đọc các bộ dữ liệu. Mô hình của chúng tôi chuyên sâu về mặt tính toán và chúng tôi thường bị giới hạn bởi thời gian chạy. (ví dụ: Không có gì lạ khi ai đó chiếm quyền điều khiển máy tính của người dân vào cuối tuần để thực hiện các hoạt động.) Chúng tôi có một mô hình tương tự được xây dựng ở Fortran không có cùng một vấn đề vì tất cả công việc đều được thực hiện trong bộ nhớ. R hoạt động như thế nào? Nó sẽ giống như SAS, ở chỗ nó hoạt động trong kho dữ liệu, đọc và viết tập tin? Hoặc nó có thể thực hiện thao tác mảng trong bộ nhớ?


Bạn thường có thể tăng tốc sas bằng cách thực hiện tất cả công việc của bạn trong một bước dữ liệu duy nhất. Điều này sẽ làm giảm thời gian I / O, vì bạn thực sự chỉ đọc dữ liệu một lần. Sử dụng nhiều thủ tục cũng sẽ làm bạn chậm lại. Ví dụ: nếu bạn lập mô hình liên tục gọi Proc glm hoặc Proc logistic (giả sử bootstrap), thì việc tạo một tập dữ liệu khổng lồ và sử dụng một câu lệnh bằng cách gọi nhiều lệnh gọi (macro sử dụng một vòng lặp% do macro) sẽ nhanh hơn. nếu bạn lập trình tốt, bạn sẽ không gặp vấn đề về thời gian do đọc và xuất tệp (ít nhất là không còn nữa so với phần mềm khác
xác suất

Ngoài ra, bạn có thể sử dụng các mảng tạm thời trong các bước dữ liệu của sas theo cách tương tự như cách bạn sẽ sử dụng ma trận trong R.
xác suất

Câu trả lời:


18

R hoạt động trong bộ nhớ - vì vậy dữ liệu của bạn cần phải phù hợp với bộ nhớ cho phần lớn các chức năng.

Gói trình biên dịch, nếu tôi nghĩ về điều bạn đang nghĩ đến ( gói trình biên dịch của Luke Tierney được cung cấp với R), không giống với ngôn ngữ được biên dịch theo nghĩa truyền thống (C, Fortran). Nó là một trình biên dịch byte cho R theo nghĩa của mã byte Java được thực thi bởi Java VM hoặc biên dịch byte mã LISP của Emacs. Nó không biên dịch mã R thành mã máy mà chỉ chuẩn bị mã R thành mã byte để nó có thể được sử dụng hiệu quả hơn mã R thô được diễn giải.

Lưu ý rằng nếu bạn đã thành lập Fortran, bạn có thể có cả hai thế giới tốt nhất; R có thể gọi các thói quen Fortran được biên dịch.


Cảm ơn! Thật tuyệt khi biết tôi có thể có đồ họa R tuyệt vời và gọi các thói quen Fortran được biên dịch. Đây có thể là câu trả lời!
Melissa

2
Chỉ cần mở rộng trên ghi chú của Gavin về bộ nhớ: xem phần trên Bộ nhớ lớn trong chế độ xem nhiệm vụ CRAN này nếu bạn đang làm việc với các tập dữ liệu lớn hơn: cran.r-project.org/web/view/HighPerformanceComputing.html
Brandon Bertelsen

1
Cũng nghĩ rằng điều quan trọng cần lưu ý là Rcpp có thể được sử dụng để đạt được hiệu suất tăng dần.
Brandon Bertelsen

Rcpp rất hữu ích để bọc C ++ để sử dụng trong / với R. Nó hỗ trợ quá trình (vô cùng) nhưng vẫn sử dụng các công cụ cơ bản của R để gọi mã được biên dịch. Nếu OP đã có mã Fortran hoặc kỹ năng Fortran, Rcpp có thể được sử dụng ít hơn.
Phục hồi Monica - G. Simpson

13

Tôi đã sử dụng được SAS15 năm và đã bắt đầu sử dụng Rnghiêm túc trong 6 tháng qua, với một số tiếng leng keng xung quanh trong một vài năm trước đó. Từ góc độ lập trình, R thực hiện thao tác dữ liệu trực tiếp, không có quy trình DATAhoặc PROC SQLquy trình tương đương vì chúng không cần thiết (cái sau sẽ hiệu quả hơn SASkhi có nhiều thao tác dữ liệu phải thực hiện từ các nguồn dữ liệu bên ngoài, ví dụ như dữ liệu quản trị). Điều này có nghĩa là, bây giờ tôi đang hiểu rõ về nó, thao tác dữ liệu nhanh hơn Rvà yêu cầu ít mã hơn.

Vấn đề chính tôi gặp phải là bộ nhớ. Không phải tất cả các gói R đều cho phép WEIGHTthông số kỹ thuật loại, vì vậy nếu bạn có SASbộ dữ liệu với các biến được sử dụng trong FREQhoặc REPLICATEcâu lệnh, bạn có thể gặp sự cố. Tôi đã xem xét các gói ffbigmemorygói trong R nhưng chúng dường như không tương thích với tất cả các gói R, vì vậy nếu bạn có bộ dữ liệu rất lớn yêu cầu các phân tích tương đối không phổ biến và đã được tổng hợp, bạn có thể gặp vấn đề với bộ nhớ.

Để tự động hóa, nếu bạn có SAS macrosthì bạn sẽ có thể lập trình tương đương Rvà chạy theo lô.

Để mã hóa R, tôi đã sử dụng Notepad++và cài đặt ngôn ngữ Rvà hiện đang khám phá những niềm vui của R Studio. Cả hai sản phẩm này đều miễn phí và đánh dấu ngôn ngữ như SASGUI cú pháp được cải thiện (tôi chỉ từng sử dụng màn hình cú pháp trong SAS).

Có một trang web , và cuốn sách liên quan, cho những người trao đổi từ SASđến R. Tôi thấy chúng hữu ích cho việc cố gắng tìm ra cách dịch một số SASlệnh sang R.

Cập nhật: một điều mà chở tôi hạt khi đến RRkhông thừa nhận tất cả mọi thứ là một tập hợp dữ liệu ( data frametrong Rcách nói), bởi vì nó không phải là một phần mềm thống kê theo cách mà SAS, SPSS, Stata, vv đang có. Vì vậy, ví dụ, tôi phải mất một thời gian để làm cho các ifcâu lệnh hoạt động vì tôi tiếp tục nhận được sự trợ giúp cho các ifcâu lệnh với vectơ (hoặc có thể là ma trận) trong khi tôi cần một ifcâu lệnh hoạt động cùng data frames. Vì vậy, các trang trợ giúp có thể cần được đọc kỹ hơn bình thường, bởi vì bạn sẽ cần kiểm tra xem lệnh bạn muốn làm sẽ hoạt động với loại đối tượng dữ liệu bạn có.

Điều vẫn khiến tôi phát điên khi học một Rlệnh mới (ví dụ: phương pháp phân tích trong gói đóng góp) là sự trợ giúp cho các lệnh thường không hoàn toàn khép kín. Tôi sẽ đến trang trợ giúp để cố gắng học lệnh và các ghi chú sử dụng thường có ...trong chúng. Đôi khi cố gắng tìm ra những gì có thể hoặc nên đi nơi mà điều đó ...đã đưa tôi vào một vòng lặp đệ quy. Sự ngắn gọn tương đối của các ghi chú trợ giúp, xuất phát từ SASđó cung cấp các ví dụ chi tiết về cú pháp và các ví dụ hoạt động với lời giải thích về nghiên cứu trong ví dụ, là một cú sốc khá lớn.


2
+1 Vui lòng xem xét cập nhật chuỗi meta của chúng tôi , nơi chúng tôi đã thu thập các liên kết đến tài nguyên phần mềm thống kê. Có một câu trả lời cho R và một câu trả lời khác cho SAS: cả hai sẽ được hưởng lợi từ việc có liên kết đến r4stats.com. (Chủ đề đó thực sự là một phần của Câu hỏi thường gặp của chúng tôi. Chúng tôi hy vọng sẽ giữ cho nó hiện tại và hữu ích.)
whuber

1
R cũng có các gói hỗ trợ truy cập SQL thông qua trình điều khiển RODBC hoặc SQLite.
DWin

1
Tôi đồng ý với ý kiến ​​của bạn về R giúp đỡ. Tôi thực sự đã chỉ ra những gì bạn đang nói trên một trong những danh sách gửi thư R nhiều năm trước. Phản hồi không tích cực. Công bằng mà nói, tôi (a) có lẽ đã không thể hiện bản thân rất tốt, và đã không đưa ra bất kỳ ví dụ cụ thể nào và (b) đã không theo đuổi vấn đề. Tóm lại, vấn đề 1 là các ví dụ quá phức tạp và liên quan đến quá nhiều khái niệm không liên quan. Các ví dụ phức tạp là Ok nhưng nên làm theo các ví dụ đơn giản. Vấn đề 2 là hầu như không có chú thích hay giải thích về những gì các ví dụ làm.
Faheem Mitha

Về chữ "trợ giúp" nhắc nhở về điều mà sếp tôi nói với tôi. "bạn học R bằng cách làm điều đó với một người đã biết R ngồi cạnh bạn tại máy tính"
xác suất

Và đối với những người khác, có sách và Stack Overflow. Vâng, tự học R là khá khó, ít nhất nó đã dành cho tôi.
Michelle

10

R là ngôn ngữ lập trình. Nó hoạt động không trong kho dữ liệu. Nó làm bất cứ điều gì bạn muốn nó làm, vì nó chỉ là một ngôn ngữ lập trình, một nô lệ cho những ham muốn của bạn, được thể hiện bằng ngôn ngữ của dấu ngoặc nhọn và dấu hai chấm.

Hãy nghĩ về nó giống như Fortran hoặc C, nhưng với véc tơ ngầm để bạn không phải lặp lại các mảng và quản lý bộ nhớ động để bạn không phải malloc () hoặc khai báo kích thước mảng bất cứ lúc nào.

Nó chủ yếu thực hiện tất cả công việc của nó trong bộ nhớ, nhưng nếu bạn muốn đọc một phần của tệp, mung nó, sau đó nhổ một số kết quả và đọc bit tiếp theo, tốt, bạn hãy tiếp tục và viết chương trình R làm điều đó

Bạn mâu thuẫn với chính mình khi nói rằng mô hình này được tính toán chuyên sâu nhưng SAS thì chậm vì I / O ... Cái này hay cái kia chắc chắn ...

Nếu bạn đã có một cái gì đó tương tự ở Fortran và bạn nói rằng bạn muốn tránh xa một ngôn ngữ được dịch, vậy tại sao bạn không làm điều đó ở Fortran?

Trình biên dịch R có thể gây ra một số tăng tốc, nhưng nếu mã R của bạn được viết tốt thì dù sao bạn cũng sẽ không nhận được bất cứ thứ gì quá lớn - không giống như viết nó bằng C hoặc Fortran.


Ah, tôi đã không giải thích chính mình. Nó chuyên sâu trong việc thao túng các bộ dữ liệu, trong SAS, có nghĩa là quá nhiều thời gian dành cho I / O. Đề nghị ban đầu của tôi là Fortran, nhưng PI quan tâm đến việc chúng tôi chuyển sang R, vì vậy anh ấy muốn tôi kiểm tra nó. Cảm ơn!
Melissa

7

Tôi hiểu rằng theo mặc định, SAS có thể hoạt động với các mô hình lớn hơn bộ nhớ, nhưng đây không phải là trường hợp của R, trừ khi bạn đặc biệt sử dụng các gói như biglm hoặc ff.

Tuy nhiên, nếu bạn đang thực hiện công việc mảng trong R có thể được véc tơ thì sẽ rất nhanh - có thể bằng một nửa tốc độ của chương trình C trong một số trường hợp, nhưng nếu bạn đang làm một cái gì đó không thể được véc tơ, thì nó sẽ có vẻ khá chậm Để cho bạn một ví dụ:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

Khi tôi tăng N lên gấp 10 đến 100.000, tôi đã bỏ bài kiểm tra 4 sau 20 phút, nhưng các bài kiểm tra 1: 3 mất 61, 3 và 37 mili giây mỗi giây

Với N = 10.000.000 thời gian cho các thử nghiệm 1: 3 là 3,3, 0,6 và 1,6 giây

Lưu ý rằng điều này đã được thực hiện trên máy tính xách tay i7 và ở mức 480mb với N = 10 triệu, bộ nhớ không phải là vấn đề.

Đối với người dùng trên các cửa sổ 32 bit, có giới hạn bộ nhớ 1,5gb cho R cho dù bạn có bao nhiêu bộ nhớ, nhưng không có giới hạn như vậy đối với các cửa sổ 64 bit hoặc linux 64 bit. Những ngày này bộ nhớ rất rẻ so với chi phí một giờ thời gian của tôi vì vậy tôi chỉ mua nhiều bộ nhớ hơn là dành thời gian cố gắng để khắc phục điều này. Nhưng điều này giả định rằng mô hình của bạn sẽ phù hợp với bộ nhớ.


1
(+1) Cảm ơn bạn đã cung cấp các minh họa hữu ích, Sean!
whuber

3

(2), lý tưởng nhất là chúng tôi muốn tạo một tệp thực thi, nhưng R thường được sử dụng làm ngôn ngữ kịch bản

Có, và đây là lý do chính đáng để chuyển sang R. Sở thích của việc viết gói R là cho phép người dùng dễ dàng làm cho các chức năng của bạn tương tác với các công cụ khác do R cung cấp, ví dụ như cung cấp cho họ dữ liệu khởi động ... hoặc bất cứ điều gì họ muốn. Nếu bạn không nghĩ rằng điều này là quan trọng, hãy sử dụng C / C ++ hoặc ngôn ngữ được biên dịch yêu thích của bạn.

Tôi muốn thêm một lời cảnh báo: bạn đã là lập trình viên, học R sẽ dễ dàng và nhanh chóng; học lập trình R hiệu quả sẽ lâu hơn. Bởi vì R được giải thích, các hằng số ẩn trongÔi() về độ phức tạp tiệm cận có thể rất lớn hoặc nhỏ ... ví dụ: nếu bạn quan tâm đến việc chạy trong dữ liệu của mình, bạn sẽ sử dụng rle() , nó sẽ nhanh (chức năng được biên dịch trước). Nếu kịch bản của bạn chính xác cùng một thuật toán, nó sẽ bị chậm (nó sẽ được diễn giải). Đây là một ví dụ cơ bản: bạn có rất nhiều thủ thuật sử dụng vectơ và ma trận, để tránh các vòng lặp diễn giải và làm cho các hàm được biên dịch trước thực hiện tất cả công việc.

Vì vậy, hãy rất cẩn thận. Sau lần thử đầu tiên, bạn chắc chắn sẽ thấy ghê tởm với R, bởi vì bạn sẽ thấy nó chậm, với một cú pháp kỳ lạ, v.v. Một khi bạn biết, nó có thể là một công cụ rất hiệu quả. Bạn thậm chí có thể kết thúc bằng cách viết kịch bản các phương thức của mình trong R dưới dạng giai đoạn sơ bộ cho mã hóa C / C ++. Giai đoạn cuối cùng sẽ là tìm hiểu API của R để tạo các hàm được biên dịch trước và bạn sẽ là một thuật sĩ R :)


2

Rõ ràng, thao tác mảng trong bộ nhớ là một điều lớn đối với SAS. Tôi không biết các chi tiết cụ thể liên quan đến R, nhưng tôi cho rằng R hoạt động trong bộ nhớ theo mặc định, vì các gói mở rộng bộ nhớ cho R, ff và bigmemory, di chuyển dữ liệu từ bộ nhớ sang đĩa. Tôi có con trỏ cho bạn nếu bạn muốn cải thiện tốc độ hoặc sử dụng bộ nhớ. Để cải thiện tốc độ, trước tiên bạn cần sử dụng R như dự định, đó là: vector hóa mã của bạn và sử dụng biên dịch mã byte. (Ngoài ra: tránh các hoạt động sao chép bộ nhớ càng nhiều càng tốt.) Thứ hai, sử dụng trình biên dịch mã được cung cấp Rprof () để xác định các bản vá chậm trong mã của bạn và viết lại chúng trong C hoặc C ++ nếu cần. Nếu bạn cần thêm bộ nhớ, bạn có thể sử dụng đối số bỏ qua trong hàm read.table () để đọc dữ liệu của mình một đoạn và bạn cũng có thể sử dụng một gói như RMyQuery, bổ sung các tiện ích thao tác cơ sở dữ liệu cho R. Nếu bạn vẫn cần thêm bộ nhớ và có thể giảm tốc độ đồng thời, bạn có thể sử dụng gói tuyết để chạy R song song. (Bạn có thể tìm thấy chi tiết về điều này, và nhiều hơn nữa, trong cuốn sách "Nghệ thuật lập trình R" của Norman Matloff, được xuất bản vào cuối năm ngoái. Chi tiết về các gói được đề cập ở đây có thể được tìm thấy trực tuyến.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.