* Re: [babel] creating simple vectors in R
2010-10-05 20:37 [babel] creating simple vectors in R Dan Davison
@ 2010-10-05 21:35 ` Erik Iverson
0 siblings, 0 replies; 2+ messages in thread
From: Erik Iverson @ 2010-10-05 21:35 UTC (permalink / raw)
To: Dan Davison; +Cc: emacs org-mode mailing list
Hello,
Dan Davison wrote:
> I'd appreciate opinions from R users on the following org-babel-R
> details:
>
I use R daily, with and without org-mode, but have never investigated
these features of passing tables and Lisp lists to source blocks, but
it looks interesting. More below.
> Currently, Org tables, and lisp lists, are converted into data frames
> when they are sent from Org to R, and we have no way to create simple
> vectors such as c(1,2). I'd like to know whether users of org and R
> would approve of the following change that makes simple R vectors
> possible, or have other suggestions related to these issues.
>
> With the patch below, there would be two ways to create a simple vector
> in R. The most direct way is to pass a non-nested lisp list:
>
> #+begin_src R :var x='(1 2) :results output
> str(x)
> #+end_src
>
> CURRENT OUTPUT:
> #+results:
> : 'data.frame': 1 obs. of 2 variables:
> : $ V1: int 1
> : $ V2: int 2
>
> NEW OUTPUT:
> #+results:
> : num [1:2] 1 2
>
What happens with "non-atomic" lists that contain mixed types?
They could either be turned into a vector of the lowest common
type, e.g., '(1 "hi") is turned into a character vector, or this
could be turned into an R list. Then you'd be going from
Lisp List -> R list data types.
> In addition, because babel's table-indexing code produces a non-nested
> list when taking a one-dimensional slice, this would be another
> situation in which a vector rather than data frame is created:
>
> #+tblname: input-tab
> | 1 | 3 |
> | 2 | 4 |
>
> #+begin_src R :var x=input-tab[0,] :results output
> str(x)
> #+end_src
>
> CURRENT OUTPUT:
> #+results:
> : 'data.frame': 1 obs. of 2 variables:
> : $ V1: int 1
> : $ V2: int 3
>
> NEW OUTPUT:
> #+results:
> : num [1:2] 1 3
>
> There's a possible argument that that's slightly at odds with R, since,
> in R, a single row slice of a data frame is still a data frame.
>
Yes, only since data.frames may and almost always do contain
mixed types. Which goes back to the first question about the
behavior of this code when there are mixed types. I think for
this case, if you're taking a single row of an org-table,
turning it into a vector is an OK thing to do, and
is something I probably would rarely do. For columns,
I definitely think it's an OK thing to do, and it's more likely
I'd be passing in a single column of an org-table as opposed
to a single row.
In R, for columns, subsets of data.frames only return data.frames
with certain indexing styles, and even then,
setting drop = TRUE will return a vector.
> df1 <- data.frame(a = 1:10, b = 2:11)
> is.vector(df1$a)
[1] TRUE
> is.vector(df1[["a"]])
[1] TRUE
> is.vector(df1[, "a"])
[1] FALSE
> is.vector(df1[, "a", drop = TRUE])
[1] TRUE
> A related issue is translating an Org table into a matrix rather than a
> data frame in R. This can be done explicitly with a call to as.matrix in
> the user's code, but if anyone feels that it would be helpful for babel
> to automate this then do say so.
>
> Dan
>
>
> diff --git a/lisp/ob-R.el b/lisp/ob-R.el
> index c709064..4b49af5 100644
> --- a/lisp/ob-R.el
> +++ b/lisp/ob-R.el
> @@ -141,16 +141,18 @@ This function is called by `org-babel-execute-src-block'."
> (defun org-babel-R-assign-elisp (name value colnames-p rownames-p)
> "Construct R code assigning the elisp VALUE to a variable named NAME."
> (if (listp value)
> - (let ((transition-file (org-babel-temp-file "R-import-")))
> - ;; ensure VALUE has an orgtbl structure (depth of at least 2)
> - (unless (listp (car value)) (setq value (list value)))
> - (with-temp-file transition-file
> - (insert (orgtbl-to-tsv value '(:fmt org-babel-R-quote-tsv-field)))
> - (insert "\n"))
> - (format "%s <- read.table(\"%s\", header=%s, row.names=%s, sep=\"\\t\", as.is=TRUE)"
> - name (org-babel-process-file-name transition-file 'noquote)
> - (if (or (eq (nth 1 value) 'hline) colnames-p) "TRUE" "FALSE")
> - (if rownames-p "1" "NULL")))
> + (if (listp (car value))
> + (let ((transition-file (org-babel-temp-file "R-import-")))
> + (with-temp-file transition-file
> + (insert (orgtbl-to-tsv value '(:fmt org-babel-R-quote-tsv-field)))
> + (insert "\n"))
> + (format "%s <- read.table(\"%s\", header=%s, row.names=%s, sep=\"\\t\", as.is=TRUE)"
> + name (org-babel-process-file-name transition-file 'noquote)
> + (if (or (eq (nth 1 value) 'hline) colnames-p) "TRUE" "FALSE")
> + (if rownames-p "1" "NULL")))
> + (format "%s <- %s"
> + name
> + (concat "c(" (mapconcat 'org-babel-R-quote-tsv-field value ",") ")")))
> (format "%s <- %s" name (org-babel-R-quote-tsv-field value))))
>
> (defvar ess-ask-for-ess-directory nil)
>
> _______________________________________________
> Emacs-orgmode mailing list
> Please use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode
^ permalink raw reply [flat|nested] 2+ messages in thread