Cómo capturar la salida del sistema()
stdout knitr (2)
Esta pregunta fue motivada por Rmarkdown y no generó resultados del comando del sistema al archivo html . Por alguna razón, la salida de system()
en R (o system2()
) no puede ser capturada por sink()
o capture.output()
, por lo que actualmente no hay forma de que knitr registre la salida. Por ejemplo, en la consola R:
> system(''ls'')
DESCRIPTION
NAMESPACE
R
README.md
inst
man
pero en un documento knitr , no verá la salida, porque capture.output(system(''ls''))
es un character(0)
, es decir, la salida no se puede capturar. Por supuesto que puedo hacer cat(system(''ls'', intern = TRUE), sep = ''/n'')
como mencioné en la respuesta de esa pregunta, pero esto es un poco incómodo. Me pregunto si es una forma de capturar la salida del system()
sin usar intern = TRUE
y cat()
.
Actualización : consulte https://github.com/yihui/knitr/issues/1203 para un truco que proporcioné para resolver el problema.
No creo que pueda hacer esto (al menos en sistemas * nix; no tengo un sistema Windows / Mac a mano) porque el system
parece devolver de manera invisible el valor devuelto por el comando ejecutado, y R no parece redirigir la salida del comando a la consola R.
Esto se debe a que el stdout
de su terminal no es el mismo que el de la consola R "stdout". Lo que se ve dentro de su sesión R es la combinación de la salida stdout
del terminal y la salida del proceso R. capture.output
está buscando la salida del proceso R, no todas las salidas a la salida stdout
del proceso principal.
Puede iniciar un proceso que se imprime en la salida stdout
, ponerlo en segundo plano, luego iniciar R ... y verá la salida de ese proceso en su "salida R", similar a si hubiera ejecutado el system("ping -c5 8.8.8.8")
de R.
josh@computer: /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
josh@computer: /home/josh
>
Podría agregar una función knitr::system
que knitr::system
base::system
. Los usuarios podrían trabajar con él como si fuera system::base
, pero la salida puede ser capturada por capture.output
:
system <- function(...) {
stopifnot(!any(names(list(...)) %in% "intern"))
result <- base::system(..., intern = TRUE)
print(result)
}
Admito que esto es un tanto intrincado y, para ser sincero, no estoy seguro de los posibles efectos secundarios. Pero creo que podría valer la pena intentarlo.