emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Aaron Ecay <aaronecay@gmail.com>
To: "Charles C. Berry" <ccberry@ucsd.edu>
Cc: emacs-orgmode@gnu.org
Subject: Re: R code block produces only partial output
Date: Sat, 16 Aug 2014 01:05:00 -0400	[thread overview]
Message-ID: <87wqa9owhv.fsf@gmail.com> (raw)
In-Reply-To: <87lhr0qimr.fsf@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 719 bytes --]

Hi Chuck, hi all,

Attached to this message is a draft patch to complete this idea.  It
should address the issue of including warnings, errors, and messages in
output.

It uses the “evaluate” R package, originally created for the knitr
literate programming system, to do most of the heavy lifting, and
includes a new mechanism to load this package into babel sessions (and
to prompt the user to install it from CRAN, if not already installed).

It does not yet address Chuck’s first issue of remote sessions, just
because I haven’t had time to look at it in detail (but I still think it
should be easy, based on the code sample/hint that Chuck gave).

What do you think of the approach broadly?

[-- Attachment #2: 0001-ob-R-overhaul-handling-of-output-results-type-in-a-s.patch --]
[-- Type: text/x-diff, Size: 5051 bytes --]

From ea99c10d148f71e5384144728a5714ecc5ae47ca Mon Sep 17 00:00:00 2001
From: Aaron Ecay <aaronecay@gmail.com>
Date: Sat, 16 Aug 2014 00:49:05 -0400
Subject: [PATCH] ob-R: overhaul handling of :output results type in a session
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/ob-R.el (org-babel-R-check-evaluate-package): New function.
(org-babel-R-initiate-session): Use it.
(org-babel-R-evaluate-session): Use the evaluate package to capture
session output.

This uses the “evaluate” R package[1] to capture the
output (incl. warnings, errors, and messages) from a babel R session.
This avoids the output showing up in the session buffer, and dodges
some previous issues with removing R prompts (>) when scraping the
output from the session buffer.

[1] <http://cran.r-project.org/web/packages/evaluate/index.html>
---
 lisp/ob-R.el | 68 +++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 49 insertions(+), 19 deletions(-)

diff --git a/lisp/ob-R.el b/lisp/ob-R.el
index 41b943c..08ef9c2 100644
--- a/lisp/ob-R.el
+++ b/lisp/ob-R.el
@@ -245,6 +245,22 @@ This function is called by `org-babel-execute-src-block'."
 	  ((stringp  value) (format "%s <- %S" name (org-no-properties value)))
 	  (t                (format "%s <- %S" name (prin1-to-string value))))))
 
+(defvar ess-execute-in-process-buffer)
+(defun org-babel-R-check-evaluate-package (&optional recursive)
+  (save-window-excursion
+    (let ((ess-execute-in-process-buffer nil)
+	  (r-buff (current-buffer)))
+      (ess-execute "library(evaluate)" nil "org-babel-R-auto")
+      (when (with-current-buffer "*org-babel-R-auto*"
+	      (goto-char (point-min))
+	      (search-forward "Error" nil t))
+	(if (and (not recursive)
+		 (y-or-n-p "Cannot load the evaluate package required for babel session support, would you like to install it from CRAN?"))
+	    (progn
+	      (message "Downloading and installing package (may take some time)")
+	      (ess-execute "install.packages(\"evaluate\")" nil "org-babel-R-auto")
+	      (org-babel-R-check-evaluate-package t))
+	  (user-error "R package evaluate is required, but not available."))))))
 
 (defvar ess-ask-for-ess-directory) ; dynamically scoped
 (defun org-babel-R-initiate-session (session params)
@@ -261,7 +277,9 @@ This function is called by `org-babel-execute-src-block'."
 	  (when (get-buffer session)
 	    ;; Session buffer exists, but with dead process
 	    (set-buffer session))
-	  (require 'ess) (R)
+	  (require 'ess)
+	  (R)
+	  (org-babel-R-check-evaluate-package)
 	  (rename-buffer
 	   (if (bufferp session)
 	       (buffer-name session)
@@ -366,7 +384,7 @@ last statement in BODY, as elisp."
 (defvar ess-eval-visibly-p)
 
 (defun org-babel-R-evaluate-session
-  (session body result-type result-params column-names-p row-names-p)
+    (session body result-type result-params column-names-p row-names-p)
   "Evaluate BODY in SESSION.
 If RESULT-TYPE equals 'output then return standard output as a
 string.  If RESULT-TYPE equals 'value then return the value of the
@@ -396,23 +414,35 @@ last statement in BODY, as elisp."
 	  (org-babel-import-elisp-from-file tmp-file '(16)))
 	column-names-p)))
     (output
-     (mapconcat
-      'org-babel-chomp
-      (butlast
-       (delq nil
-	     (mapcar
-	      (lambda (line) (when (> (length line) 0) line))
-	      (mapcar
-	       (lambda (line) ;; cleanup extra prompts left in output
-		 (if (string-match
-		      "^\\([ ]*[>+\\.][ ]?\\)+\\([[0-9]+\\|[ ]\\)" line)
-		     (substring line (match-end 1))
-		   line))
-	       (org-babel-comint-with-output (session org-babel-R-eoe-output)
-		 (insert (mapconcat 'org-babel-chomp
-				    (list body org-babel-R-eoe-indicator)
-				    "\n"))
-		 (inferior-ess-send-input)))))) "\n"))))
+     (let* ((output-file (org-babel-temp-file "R-"))
+	    (sentinel-file (concat output-file "-sentinel")))
+       (org-babel-comint-eval-invisibly-and-wait-for-file
+	session sentinel-file
+	(format
+"
+tryCatch(.org.eval.result <- evaluate(%S, new_device = FALSE, stop_on_error = 0L),
+         finally = {
+             capture.output(
+                 withCallingHandlers(
+                     replay(Filter(function (x) !inherits(x, \"source\"),
+                                   .org.eval.result)),
+                     message = function (x) {
+                         cat(x$message);
+                         invokeRestart(\"muffleMessage\")
+                     }),
+                 file=%S)
+             file.create(%S)
+         })
+"
+		(org-babel-chomp body)
+		output-file
+		sentinel-file))
+       (with-temp-buffer
+	 (insert-file-contents output-file)
+	 (goto-char (point-min))
+	 (flush-lines "^$")
+	 (delete-trailing-whitespace)
+	 (buffer-string))))))
 
 (defun org-babel-R-process-value-result (result column-names-p)
   "R-specific processing of return value.
-- 
2.0.4


[-- Attachment #3: Type: text/plain, Size: 25 bytes --]


Thanks,

-- 
Aaron Ecay

  parent reply	other threads:[~2014-08-16  5:05 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-04 11:18 R code block produces only partial output Andreas Kiermeier
2014-08-04 11:53 ` Eric Schulte
2014-08-04 12:23   ` Andreas Kiermeier
2014-08-04 13:10     ` Eric Schulte
2014-08-05  0:46       ` Andreas Kiermeier
2014-08-05  4:00         ` John Hendy
2014-08-05  4:31           ` Andreas Kiermeier
2014-08-05 18:05       ` Charles Berry
2014-08-05 19:02         ` Eric Schulte
2014-08-05 19:11           ` John Hendy
2014-08-05 19:57             ` Nick Dokos
2014-08-05 20:10               ` Nick Dokos
2014-08-05 22:21             ` Charles C. Berry
2014-08-06  3:32           ` Aaron Ecay
2014-08-06 11:30             ` Eric Schulte
2014-08-07  6:00               ` Aaron Ecay
2014-08-07 17:42                 ` Charles C. Berry
2014-08-07 18:06                   ` Aaron Ecay
2014-08-07 18:42                     ` Charles C. Berry
2014-08-07 19:06                       ` Thomas S. Dye
2014-08-09  8:54                       ` Rainer M Krug
2014-08-16  5:05                     ` Aaron Ecay [this message]
2014-08-16 18:50                       ` Charles C. Berry
2014-08-16 20:58                         ` Aaron Ecay
2014-08-17  6:03                           ` Achim Gratz
2014-08-19  0:13                             ` Aaron Ecay
2014-08-19  5:36                               ` Achim Gratz
2014-08-23  8:32                                 ` Aaron Ecay
2014-08-23  9:24                                   ` Andreas Kiermeier
2014-08-23 17:10                                   ` Aaron Ecay
2014-08-23 18:35                                   ` Thomas S. Dye
2014-08-23 19:37                                     ` Ista Zahn
2014-08-24  0:10                           ` Charles C. Berry
2014-08-28  5:24                             ` Aaron Ecay
2014-09-01  5:00                               ` Aaron Ecay
2014-09-01 16:08                                 ` Charles C. Berry
2014-08-09  8:48                   ` Rainer M Krug
2014-08-06  1:11         ` Andreas Kiermeier
2014-08-06  2:21           ` Charles C. Berry
2014-08-06  3:24             ` Aaron Ecay
2014-08-06 15:59               ` Charles C. Berry

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wqa9owhv.fsf@gmail.com \
    --to=aaronecay@gmail.com \
    --cc=ccberry@ucsd.edu \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).