how to create a quoted expression from strings
Asked Answered
S

3

12

Given a vector of strings, I would like to create an expression without the quotation marks.

# eg, I would like to go from 
c("string1", "string2")

# to...  (notice the lack of '"' marks)
quote(list(string1, string2))

I am encountering some difficulty dropping the quotation marks

input <- c("string1", "string2")
output <- paste0("quote(list(", paste(input, collapse=","), "))")

# not quite what I am looking for.     
as.expression(output)
expression("quote(list(string1,string2))")



This is for use in data.table column selection, in case relevant.
What I am looking for should be able to fit into data.table as follows:
library(data.table)
mydt <- data.table(id=1:3, string1=LETTERS[1:3], string2=letters[1:3])

result <- ????? # some.function.of(input)
> mydt[ , eval( result )]
   string1 string2
1:       A       a
2:       B       b
3:       C       c
Sigmatism answered 4/2, 2013 at 23:35 Comment(2)
I tend to use as.quoted from the plyr package. eg output <- paste0("list(", paste(input, collapse=","), ")"); as.quoted(output)[[1]]. I also find sprintf useful, eg sprintf('list(%s)', paste(input, collapse = ', '))Cornellcornelle
This has been very helpful to me: github.com/hadley/devtools/wiki/EvaluationSmallwood
K
12

Here is what I'd do:

## Create an example of a data.table "dt" whose columns you want to index 
## using a character vector "xx"
library(data.table)
dt <- data.table(mtcars)
xx <- c("wt", "mpg")

## Construct a call object identical to that produced by quote(list("wt", "mpg"))
jj <- as.call(lapply(c("list", xx), as.symbol))

## Try it out
dt[1:5,eval(jj)]
#       wt  mpg
# 1: 2.620 21.0
# 2: 2.875 21.0
# 3: 2.320 22.8
# 4: 3.215 21.4
# 5: 3.440 18.7

When "computing on the language" like this, it's often helpful to have a look at the structure of the object you're trying to construct. Based on the following (and once you know about as.call() and as.symbol()), creating the desired language object becomes a piece of cake:

x <- quote(list(wt, mpg))

str(x)
#  language list(wt, mpg)

class(x)
# [1] "call"

str(as.list(x))
# List of 3
#  $ : symbol list
#  $ : symbol wt
#  $ : symbol mpg
Khaddar answered 4/2, 2013 at 23:47 Comment(3)
thank you Josh! I was unfamiliar with as.symbol. This works perfectly.Sigmatism
Yeah, it comes in handy from time to time. You can also call it by as.name(), if that turns out to be easier to remember.Tektite
and thanks as well for the added reference material. That is in fact exactly where I am headed. CheersSigmatism
C
5

I tend to use as.quoted from the plyr package

 outputString <- sprintf('list(%s)', paste(input, collapse = ', ')) 


 library(plyr)
  output <- as.quoted(outputString)[[1]]

  mydt[, eval(output)]
   string1 string2
1:       A       a
2:       B       b
3:       C       c

However if it is simply column selection, you can pass the string and use .. (which, like in the Unix terminal, means to "look up one level")

mydt[ , ..input]
   string1 string2
1:       A       a
2:       B       b
3:       C       c
Cornellcornelle answered 4/2, 2013 at 23:47 Comment(0)
U
0

I found these answers helpful but incomplete for using variables and multiple lines within the expression. To create a quoted expression from strings, with variables and multiple lines make use of quote(), atop() and subsititute():

  # Prepare variables
  samp_skewness = round(skewness(dv),2)
  samp_kurtosis = round(kurtosis(dv),2)
  samp_var = round(var(dv))
  samp_summ <- summary(dv)
  num_samples = length(dv)

  # Prepare quotes containing math annotations
  q1 = quote(paste(mu,"="))
  q2 = quote(paste(sigma,"="))
  q3 = quote(paste(gamma[1],"="))
  q4 = quote(paste(gamma[2],"="))

# Use subsitition to construct the expression, passing in the variables and quoted expressions
  title = substitute(atop(paste("Top Title, # samples: ", ns), 
            paste(e1,v1,", ",e2,v2,", ",e3,v3,", ",e4,v4)),
            list(ns=num_samples,v1=round(samp_summ['Mean']),v2=samp_var,
            v3=samp_skewness,v4=samp_kurtosis,e1=q1,e2=q2,e3=q3,e4=q4))

In ggplot: ...

labs(title = title) +

...

Upstate answered 4/4, 2015 at 18:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.