2016-04-29 20 views
16

Câu hỏi này được thúc đẩy bởi Rmarkdown not outputting results of system command to html file. Vì một số lý do, đầu ra của system() trong R (hoặc system2()) không thể bị bắt bởi sink() hoặc capture.output(), vì vậy hiện tại không có cách nào cho knitr để ghi lại đầu ra. Ví dụ, trong R console:Cách nắm bắt đầu ra của hệ thống()

> system('ls') 
DESCRIPTION 
NAMESPACE 
R 
README.md 
inst 
man 

nhưng trong một tài liệu knitr, bạn sẽ không nhìn thấy đầu ra, vì capture.output(system('ls'))character(0), ví dụ đầu ra không thể bị bắt. Tất nhiên tôi có thể làm cat(system('ls', intern = TRUE), sep = '\n') như tôi đã đề cập trong câu trả lời của câu hỏi đó, nhưng đây là loại vụng về. Tôi tự hỏi nếu đó là một cách để nắm bắt đầu ra của system() mà không cần sử dụng intern = TRUEcat().


Cập nhật: xem https://github.com/yihui/knitr/issues/1203 cho một hack mà tôi cung cấp để giải quyết vấn đề.

Trả lời

4

Bạn có thể thêm hàm knitr::system mặt nạ base::system. Người dùng có thể làm việc với nó như nó là system::base, nhưng sản lượng có thể được chụp bởi capture.output:

system <- function(...) { 
    stopifnot(!any(names(list(...)) %in% "intern")) 
    result <- base::system(..., intern = TRUE) 
    print(result) 
} 

Tôi thừa nhận, rằng đây là một chút hacky, và phải trung thực, tôi không chắc chắn về tác dụng phụ có thể. Nhưng tôi nghĩ nó có thể đáng để thử.

+0

Cảm ơn! Tôi đã nhận thức được điều này nhưng tôi không sử dụng nó nếu tôi có thể tìm thấy một cách để nắm bắt đầu ra của 'system()'. Xem bình luận của tôi dưới câu trả lời của Joshua Ulrich. –

+0

@Yihui nó không * rằng * xấu - đặc biệt là biết rằng các tùy chọn 'ignore.stdout' và' ignore.stderr' trong 'system' chỉ cần thêm'>/dev/null' hoặc '2>/dev/null' chuyển hướng đến 'lệnh' :) – daroczig

5

Tôi không nghĩ rằng bạn có thể làm điều này (ít nhất là trên hệ thống * nix; tôi không có hệ thống Windows/Mac tiện dụng) vì system dường như vô hình trả về giá trị được trả về bởi lệnh được thực thi và R không không xuất hiện để chuyển hướng đầu ra của lệnh tới bảng điều khiển R.

Điều này là do stdout của thiết bị đầu cuối của bạn không giống với giao diện điều khiển R "stdout". Những gì bạn nhìn thấy từ bên trong phiên R của bạn là sự kết hợp của thiết bị đầu cuối của stdout và đầu ra quá trình R. capture.output đang tìm kiếm đầu ra của quá trình R, không phải tất cả đầu ra là stdout từ quy trình gốc.

Bạn có thể bắt đầu quá trình in thành stdout, đặt nó ở chế độ nền, sau đó bắt đầu R ... và bạn sẽ thấy quá trình 'xuất trong "đầu ra R" của bạn, tương tự như bạn đã chạy system("ping -c5 8.8.8.8") từ R.

[email protected]: /home/josh 
> ping -c5 8.8.8.8 & R 
[1] 5808 
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 
64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=39.9 ms 

R version 3.2.4 Revised (2016-03-16 r70336) -- "Very Secure Dishes" 
Copyright (C) 2016 The R Foundation for Statistical Computing 
Platform: x86_64-pc-linux-gnu (64-bit) 

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. 

    Natural language support but running in an English locale 

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. 

> 64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=38.1 ms 
64 bytes from 8.8.8.8: icmp_seq=3 ttl=46 time=38.3 ms 
64 bytes from 8.8.8.8: icmp_seq=4 ttl=46 time=38.4 ms 
64 bytes from 8.8.8.8: icmp_seq=5 ttl=46 time=38.3 ms 

--- 8.8.8.8 ping statistics --- 
5 packets transmitted, 5 received, 0% packet loss, time 4003ms 
rtt min/avg/max/mdev = 38.176/38.656/39.986/0.703 ms 

> q() 
Save workspace image? [y/n/c]: n 
[1]+ Done     ping -c5 8.8.8.8 

[email protected]: /home/josh 
> 
+1

Tôi không nghĩ giá trị trả về vô hình là vấn đề. Tôi mong đợi 'capture.output()' để capture stdout, mặc dù đó không phải là những gì được ghi lại (tài liệu sử dụng một từ mơ hồ "output" và tôi không biết nếu nó ngụ ý stdout). Ví dụ, bạn có thể 'capture.output ((function() {print (" Hello world! "); Invisible (" hi ")})())' và nó bắt 'Hello world!' Từ 'print()' . Câu hỏi thực sự của tôi là tại sao đầu ra của 'print()' có thể được bắt, nhưng đầu ra của 'system()' có thể không. Nó là một trong hai 'system()' không ghi vào stdout, hoặc 'capture.output()' không thực sự capture stdout. –

+0

@Yihui không phải tôi là chuyên gia về R internals, nhưng [this] (https://github.com/wch/r-source/blob/e5b21d0397c607883ff25cca379687b86933d730/src/unix/sys-unix.c#L337) dòng _does_ dường như đề nghị 'hệ thống' đang sử dụng' stdout' (trái với mong đợi của tôi) – MichaelChirico

+0

@MichaelChirico Cảm ơn bạn đã đào sâu vào mã C. Sau đó, tôi đoán câu hỏi tiếp theo của tôi là loại đầu ra 'capture.output()' thực sự nắm bắt được. –

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