Cách tốt nhất để sử dụng tập lệnh R trên dòng lệnh (thiết bị đầu cuối) là gì?


115

Rất tiện lợi khi có các tập lệnh R để thực hiện các âm mưu đơn giản từ dòng lệnh. Tuy nhiên, chạy R từ các tập lệnh bash không thuận tiện chút nào. Lý tưởng có thể là một cái gì đó giống như

#!/path/to/R
...

hoặc là

#!/usr/bin/env R
...

nhưng tôi đã không thể làm cho một trong hai công việc đó.

Một lựa chọn khác là giữ các tập lệnh hoàn toàn ở dạng R, ví dụ script.R, và gọi nó bằng R --file=script.Rhoặc tương tự. Tuy nhiên, đôi khi một tập lệnh sẽ dựa vào các công tắc dòng lệnh khó hiểu tại thời điểm đó một phần của mã tồn tại bên ngoài tập lệnh. Ví dụ: lén đưa mọi thứ vào R từ bash thông qua một tệp .Rprofile cục bộ, các công tắc mong muốn sau đó đều --vanillangụ ý ngoại trừ --no-init-file.

Một tùy chọn khác là một tập lệnh bash để lưu trữ các cờ R và có thể thực thi dễ dàng, sau đó gọi là tập lệnh R. Vấn đề là điều này có nghĩa là một chương trình đơn lẻ chỉ được tách thành hai tệp mà bây giờ phải được đồng bộ hóa, chuyển sang các máy mới cùng nhau, v.v.

Tùy chọn mà tôi hiện không coi thường nhất là nhúng R vào một tập lệnh bash:

#!/bin/bash
... # usage message to catch bad input without invoking R
... # any bash pre-processing of input
... # etc
R --random-flags <<RSCRIPT
# R code goes here
RSCRIPT

Mọi thứ đều nằm trong một tệp duy nhất. Nó có thể thực thi và dễ dàng xử lý các đối số. Vấn đề là việc kết hợp bash và R như thế này khá nhiều loại trừ khả năng bất kỳ IDE nào không bị lỗi ở cái này hay cái khác, và khiến trái tim tôi đau thật.

Có cách nào tốt hơn tôi đang thiếu không?

Câu trả lời:


132

Nội dung của script.r:

#!/usr/bin/env Rscript

args = commandArgs(trailingOnly = TRUE)
message(sprintf("Hello %s", args[1L]))

Dòng đầu tiên là dòng shebang . Cách tốt nhất là sử dụng /usr/bin/env Rscriptthay vì mã hóa cứng đường dẫn đến cài đặt R của bạn. Nếu không, bạn có nguy cơ phá vỡ tập lệnh của mình trên các máy tính khác.

Tiếp theo, làm cho nó thực thi được (trên dòng lệnh):

chmod +x script.r

Lời mời từ dòng lệnh:

./script.r world
# Hello world

1
Vâng, tôi nghĩ đây là cách "chính thức" để làm điều đó.
Frank,

5
Và chạy Rscript --helptừ dòng lệnh sẽ liệt kê rất nhiều tùy chọn hữu ích có thể thêm vào shebang, chẳng hạn như --vanilla.
flodel

8
Cũng hãy đề cập đến commandArgshàm và các gói getoptoptparsephân tích cú pháp dòng lệnh. Vì vậy, các đối số và tùy chọn cũng có thể được chuyển đến các tập lệnh của bạn khi chạy từ dòng lệnh.
flodel

1
Lưu ý rằng điều này chỉ hoạt động nếu #!/usr/bin/Rscript( không phải là thông lệ tiêu chuẩn cho các tập lệnh R).
gented

16

Hãy thử nhỏ hơn . littlercung cấp khả năng hash-bang (tức là tập lệnh bắt đầu bằng #! / some / path) cho GNU R, cũng như sử dụng dòng lệnh và đường ống đơn giản.


10

Phản ứng của Miguel Sanchez là đúng như vậy. Cách khác để thực thi Rscript có thể là lệnh 'env' để chạy RScript trên toàn hệ thống.

#!/usr/bin/env Rscript

1
Không phải "toàn hệ thống", mà là envcho phép bạn chạy cái đầu tiên Rscriptđược tìm thấy của riêng bạn $PATH, do đó cho phép một cái thực sự chạy thứ gì đó khác với toàn hệ thống / mặc định Rscript(có thể không được cài đặt trong /usr/whatever). Tôi khuyên bạn nên sử dụng envfor Rand Rscript, vì những thứ này đặc biệt có thể không được cài đặt ở những nơi tiêu chuẩn. ( bashTuy nhiên, các tập lệnh thông thường luôn có thể sử dụng một cách an toàn #!/bin/bash.)
michael

@michael Không, bạn đã nhầm về Bash, và đây là lời khuyên nguy hiểm. Điều duy nhất có thể được mã hóa cứng một cách an toàn là /bin/sh. Mọi thứ khác phải sử dụng envtra cứu. Đặc biệt, thường thì Bash đã lỗi thời trên các cụm máy tính và người dùng có các cài đặt tùy chỉnh của riêng họ (thường ở ~/.local/binhoặc được chia sẻ trong thứ gì đó như /softwarengàm NFS). Tương tự như vậy, trên hệ điều hành MacOS, /bin/bashđược luôn luôn lỗi thời do việc cấp phép các vấn đề, và cập nhật Bash được phổ biến hơn tọa lạc tại /usr/local/bin/bash(Tôi nhận thấy nhận xét của bạn là 3 tuổi nhưng điều này là khá quan trọng.)
Konrad Rudolph

Không, xin lỗi, điều đó đơn giản là không đúng. Tuy nhiên, bạn có ý kiến ​​mạnh mẽ về vấn đề này, vì vậy tôi sẽ không tranh luận về vấn đề này. Nếu việc sử dụng /bin/sh, trong bất kỳ hoàn cảnh nào, cũng không phải là "nguy hiểm", thì bạn phải thừa nhận điều tương tự có thể nói /bin/bash. Việc sử dụng envkhó dự đoán hơn, do PATHcài đặt đáng tin cậy / không nhất quán cho những người dùng khác nhau, nhưng mỗi người dùng R có thể thực sự muốn hành vi này, trong khi bashcác tập lệnh thì không. Cuối cùng, đối với CI / đám mây gọi các tập lệnh bash mới hơn, chỉ cần gọi chúng bằng cách sử dụng /path/to/my/bash myscripthoặc thiết lập rõ ràng đường dẫn & gọi chúng bằng cách sử dụng env script. EOT
michael

9

#!/path/to/Rsẽ không hoạt động vì bản thân R là một tập lệnh, vì vậy execvekhông vui.

tôi sử dụng R --slave -f script


4
Fyi đối với độc giả bình thường: rất nhiều câu trả lời được ghi trước Rscript(và littler), trong trường hợp bạn đang thắc mắc.
michael

@michael Không có câu trả lời nào ở đây có trước Rscript, được phát hành vào năm 2007 với R 2.5.0.
Konrad Rudolph


4

Những công việc này,

#!/usr/bin/Rscript

nhưng tôi không biết điều gì sẽ xảy ra nếu bạn có nhiều hơn 1 phiên bản R được cài đặt trên máy của mình.

Nếu bạn làm như thế này

#!/usr/bin/env Rscript

nó yêu cầu trình thông dịch chỉ sử dụng bất cứ thứ gì R xuất hiện đầu tiên trên đường dẫn của bạn.


2

Nếu chương trình bạn đang sử dụng để thực thi tập lệnh của bạn cần các tham số, bạn có thể đặt chúng ở cuối dấu #! hàng:

#!/usr/bin/R --random --switches --f

Không biết R, tôi không thể kiểm tra đúng cách, nhưng điều này dường như hoạt động:

axa@artemis:~$ cat r.test
#!/usr/bin/R -q -f
error
axa@artemis:~$ ./r.test
> #!/usr/bin/R -q -f
> error
Error: object "error" not found
Execution halted
axa@artemis:~$

2

Chỉ cần một ghi chú để thêm vào bài đăng này. Các phiên bản sau của Rdường như đã bị chôn vùi Rscriptphần nào. Đối với R 3.1.2-1 trên OSX được tải xuống tháng 1 năm 2015, tôi thấy Rscripttrong

/sw/Library/Frameworks/R.framework/Versions/3.1/Resources/bin/Rscript

Vì vậy, thay vì những thứ như thế #! /sw/bin/Rscript, tôi cần sử dụng phần sau ở đầu tập lệnh của mình.

#! /sw/Library/Frameworks/R.framework/Versions/3.1/Resources/bin/Rscript

locate Rscriptthể hữu ích cho bạn.


Câu trả lời này có khả năng hữu ích, vì không rõ OP đề cập đến nền tảng nào (* nix hoặc Mac OS). Với một chút làm việc lại (tìm mã định dạng và xóa phần đầu có lỗi), đây sẽ là một bổ sung tốt cho các câu trả lời ở đây.
BenBarnes

2
Đây là một lý do khác để sử dụng #!/usr/bin/env Rscriptthay vì một con đường mã hóa cứng trong Rkịch bản (và thêm rằng con đường dài để bạn $PATH)
michael

0

Bạn có thể muốn sử dụng mô-đun rpy2 của python. Tuy nhiên, cách "đúng" để làm điều này là với R CMD BATCH. Bạn có thể sửa đổi điều này để ghi vào STDOUT, nhưng mặc định là ghi vào tệp .Rout. Xem ví dụ bên dưới:

[ramanujan:~]$cat foo.R
print(rnorm(10))
[ramanujan:~]$R CMD BATCH foo.R
[ramanujan:~]$cat foo.Rout

R version 2.7.2 (2008-08-25)
Copyright (C) 2008 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

[Previously saved workspace restored]


 ~/.Rprofile loaded.
Welcome at  Fri Apr 17 13:33:17 2009
> print(rnorm(10))
 [1]  1.5891276  1.1219071 -0.6110963  0.1579430 -0.3104579  1.0072677 -0.1303165  0.6998849  1.9918643 -1.2390156
>

Goodbye at  Fri Apr 17 13:33:17 2009
> proc.time()
   user  system elapsed
  0.614   0.050   0.721

Lưu ý: bạn sẽ muốn thử --vanilla và các tùy chọn khác để loại bỏ tất cả các lỗi khởi động.


0

Hãy thử smallR để viết các tập lệnh R nhanh trong dòng lệnh:

http://code.google.com/p/simple-r/

( rlệnh trong thư mục)

Sơ đồ từ dòng lệnh sử dụng smallR sẽ giống như sau:

r -p file.txt

2
Thay vì điều này (có vẻ như đã chết), littlerchắc chắn sẽ được ưa thích hơn (vì nó vẫn còn sống); hoặc, chỉ cần sử dụng Rscript(thực sự ra mắt sau khi littlerđược tạo.)
michael

-1

Phần sau phù hợp với tôi khi sử dụng MSYS bash trên Windows - Tôi không có R trên hộp Linux của mình nên không thể thử ở đó. Bạn cần hai tệp - tệp đầu tiên được gọi là runr thực thi R với một tham số tệp

# this is runr
# following is path to R on my Windows machine
# plus any R params you need
c:/r/bin/r --file=$1

Bạn cần thực thi điều này bằng chmod + x runr .

Sau đó, trong tệp script của bạn:

#!runr
# some R commands
x = 1
x

Lưu ý dấu #! dòng runr có thể cần bao gồm đường dẫn đầy đủ đến runr, tùy thuộc vào cách bạn đang sử dụng lệnh, cách biến PATH của bạn được đặt, v.v.

Không đẹp, nhưng nó có vẻ hoạt động!


1
Điều gì về các tập lệnh R khác nhau cần các tham số khác nhau? Điều gì về việc truyền các đối số cho các tập lệnh R từ dòng lệnh?
blahdiblah
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.