2012-11-20 6 views
6

Tôi có một kịch bản (gọi nó là Main.R) có đoạn mã sau để tìm bản thân khi tôi chạy nó:Làm thế nào một tập lệnh có thể tìm thấy chính nó trong R chạy từ dòng lệnh?

frame_files <- lapply(sys.frames(), function(x) x$ofile) 
frame_files <- Filter(Negate(is.null), frame_files) 
main.dir <- dirname(dirname(frame_files[[length(frame_files)]])) 

này được sử dụng để có được những thư mục trên thư mục riêng của mình, main.dir, được sử dụng để gọi các tập lệnh khác liên quan đến đường dẫn này.

Tôi quan tâm đến chạy kịch bản này từ một dòng lệnh, ví dụ

R CMD BATCH Main.R 

hoặc

Rscript Main.R 

Thật không may, các lệnh ở trên không hoạt động khi tôi gọi là kịch bản từ lệnh hàng.

Có mã nào tôi có thể đặt trong Main.R hoặc tùy chọn cuộc gọi tới R hoặc Rscript mà tôi có thể sử dụng thay thế không?

Cụ thể hơn, giải pháp sẽ cần phải hoạt động trong Windows.

+0

Điều này có hữu ích không? http://stackoverflow.com/questions/750786/whats-the-best-way-to-use-r-scripts-on-the-command-line – atomh33ls

+0

Để công bằng, tôi không chắc chắn, nhưng nó không ' t trông giống như nó. Tôi phải nói, tôi không giỏi sử dụng dòng lệnh. Tôi đã chỉnh sửa bài viết của tôi để thêm rằng tôi đang sử dụng Windows, tôi không biết nếu nó làm cho một sự khác biệt trong câu trả lời. Đọc một số bài viết khác, tôi nhận được ấn tượng #! không hoạt động trong Windows. – J4y

Trả lời

8

Dưới đây là một giải pháp mà sẽ cung cấp cho bạn đường dẫn thư mục tập tin chính xác khi kịch bản được điều hành hoặc với source hoặc với Rscript.

# this is wrapped in a tryCatch. The first expression works when source executes, the 
# second expression works when R CMD does it. 
full.fpath <- tryCatch(normalizePath(parent.frame(2)$ofile), # works when using source 
       error=function(e) # works when using R CMD 
        normalizePath(unlist(strsplit(commandArgs()[grep('^--file=', commandArgs())], '='))[2])) 
dirname(full.fpath) 

Chìa khóa cho đây là chức năng normalizePath. Đặt tên đường dẫn tương đối hoặc viết tắt, normalizePath sẽ trả lại đường dẫn hợp lệ hoặc tăng lỗi. Khi chạy tập lệnh từ Rscript, nếu bạn cung cấp cho normalizePath tên tệp cơ sở của tập lệnh hiện tại, nó sẽ trả lại đường dẫn đầy đủ, bất kể thư mục hiện tại của bạn là gì. Nó thậm chí có được đường dẫn ngay khi bạn cung cấp một đường dẫn tương đối đến R CMD và có một kịch bản có cùng tên trong thư mục hiện hành!

Trong đoạn mã trên, tôi trích xuất tên tệp từ một trong các chuỗi được trả về bởi commandArgs. Nếu bạn nhìn vào đầu ra của commandArgs, bạn sẽ thấy rằng tên tệp là đối số thứ tư. Đối số được ghi là '--file = yourscript.R', vì vậy trong dòng cuối cùng ở trên, tôi chia chuỗi thành '=' và kéo ra tên tệp.

+1

+1 - nhưng chạy 'Rscript' với các tùy chọn bổ sung, như' --vanilla' và '--file = [...]' có thể kết thúc ở bất kỳ đâu. Sẽ khôn ngoan hơn khi sử dụng hàm 'grep' như tìm nó thay vì sử dụng vị trí được mã hóa cứng như' 4'. – flodel

+0

Cảm ơn bạn đã chú ý đến điều này. Bỏ nó ra vì lợi ích ngắn gọn. –

+0

@mplourde Cảm ơn! Tôi đã không nhận thức được 'normalizePath'.Tôi thích rằng bạn có tất cả trong đó với 'tryCatch'. – J4y

1

Ý tưởng là cung cấp đường dẫn làm đối số cho Main.R

Tôi giả sử Bạn gọi nó bằng RScript.

Rscript Main.R 'path' 

trong Main.R của bạn, bạn thêm đoạn mã để đọc các luận

args <- commandArgs(trailingOnly = TRUE) 
mainpath <- as.character(args[1])