org-babel-R.el 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. ;;; org-babel-R.el --- org-babel functions for R code evaluation
  2. ;; Copyright (C) 2009 Eric Schulte
  3. ;; Author: Eric Schulte
  4. ;; Keywords: literate programming, reproducible research, R, statistics
  5. ;; Homepage: http://orgmode.org
  6. ;; Version: 0.01
  7. ;;; License:
  8. ;; This program is free software; you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation; either version 3, or (at your option)
  11. ;; any later version.
  12. ;;
  13. ;; This program is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;;
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  20. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. ;; Boston, MA 02110-1301, USA.
  22. ;;; Commentary:
  23. ;; Org-Babel support for evaluating R code
  24. ;;; Code:
  25. (require 'org-babel)
  26. (org-babel-add-interpreter "R")
  27. (defvar org-babel-R-buffer "org-babel-R"
  28. "Holds the buffer for the current R process")
  29. (defun org-babel-R-initiate-R-buffer ()
  30. "If there is not a current R process then create one."
  31. (unless (org-babel-comint-buffer-livep org-babel-R-buffer)
  32. (save-window-excursion (R) (setf org-babel-R-buffer (current-buffer)))))
  33. (defun org-babel-execute:R (body params)
  34. "Execute a block of R code with org-babel. This function is
  35. called by `org-babel-execute-src-block'."
  36. (message "executing R source code block...")
  37. (save-window-excursion
  38. (let ((vars (org-babel-ref-variables params))
  39. (results-params (split-string (cdr (assoc :results params))))
  40. results)
  41. (org-babel-R-initiate-R-buffer)
  42. (mapc (lambda (pair) (org-babel-R-assign-elisp (car pair) (cdr pair))) vars)
  43. (cond
  44. ((member "script" results-params) ;; collect all output
  45. (let ((tmp-file (make-temp-file "org-babel-R-script-output")))
  46. (org-babel-comint-input-command org-babel-R-buffer (format "sink(%S)" tmp-file))
  47. (org-babel-comint-input-command org-babel-R-buffer body)
  48. (org-babel-comint-input-command org-babel-R-buffer "sink()")
  49. (with-temp-buffer (insert-file-contents tmp-file) (buffer-string))))
  50. ((member "last" results-params) ;; the value of the last statement
  51. (org-babel-comint-input-command org-babel-R-buffer body)
  52. (org-babel-R-last-value-as-elisp))))))
  53. (defun org-babel-R-quote-tsv-field (s)
  54. "Quote field S for export to R."
  55. (if (stringp s)
  56. (concat "\"" (mapconcat 'identity (split-string s "\"") "\"\"") "\"")
  57. (format "%S" s)))
  58. (defun org-babel-R-assign-elisp (name value)
  59. "Read the elisp VALUE into a variable named NAME in the current
  60. R process in `org-babel-R-buffer'."
  61. (unless org-babel-R-buffer (error "No active R buffer"))
  62. (org-babel-comint-input-command
  63. org-babel-R-buffer
  64. (if (listp value)
  65. (let ((transition-file (make-temp-file "org-babel-R-import")))
  66. ;; ensure VALUE has an orgtbl structure (depth of at least 2)
  67. (unless (listp (car value)) (setq value (list value)))
  68. (with-temp-file transition-file
  69. (insert (orgtbl-to-tsv value '(:fmt org-babel-R-quote-tsv-field)))
  70. (insert "\n"))
  71. (format "%s <- read.table(\"%s\", header=FALSE, sep=\"\\t\", as.is=TRUE)"
  72. name transition-file))
  73. (format "%s <- %s" name (org-babel-R-quote-tsv-field value)))))
  74. (defun org-babel-R-last-value-as-elisp ()
  75. "Return the last value returned by R as Emacs lisp."
  76. (let ((tmp-file (make-temp-file "org-babel-R")) result)
  77. (org-babel-comint-input-command
  78. org-babel-R-buffer
  79. (format "write.table(.Last.value, file=\"%s\", sep=\"\\t\", na=\"nil\",row.names=FALSE, col.names=FALSE, quote=FALSE)"
  80. tmp-file))
  81. (with-temp-buffer
  82. (condition-case nil
  83. (progn
  84. (org-table-import tmp-file nil)
  85. (delete-file tmp-file)
  86. (setq result (mapcar (lambda (row)
  87. (mapcar #'org-babel-R-read row))
  88. (org-table-to-lisp))))
  89. (error nil))
  90. (if (null (cdr result)) ;; if result is trivial vector, then scalarize it
  91. (if (consp (car result))
  92. (if (null (cdr (car result)))
  93. (caar result)
  94. result)
  95. (car result))
  96. result))))
  97. (defun org-babel-R-read (cell)
  98. "Strip nested \"s from around strings in exported R values."
  99. (org-babel-read (or (and (stringp cell)
  100. (string-match "\\\"\\(.+\\)\\\"" cell)
  101. (match-string 1 cell))
  102. cell)))
  103. (provide 'org-babel-R)
  104. ;;; org-babel-R.el ends here