Getting strings recognized as variable names in R

Hendy picture Hendy · Jan 29, 2012 · Viewed 118k times · Source

Related: Strings as variable references in R
Possibly related: Concatenate expressions to subset a dataframe


I've simplified the question per the comment request. Here goes with some example data.

dat <- data.frame(num=1:10,sq=(1:10)^2,cu=(1:10)^3)
set1 <- subset(dat,num>5)
set2 <- subset(dat,num<=5)

Now, I'd like to make a bubble plot from these. I have a more complicated data set with 3+ colors and complicated subsets, but I do something like this:

symbols(set1$sq,set1$cu,circles=set1$num,bg="red")
symbols(set2$sq,set2$cu,circles=set2$num,bg="blue",add=T)

I'd like to do a for loop like this:

colors <- c("red","blue")
sets <- c("set1","set2")
vars <- c("sq","cu","num")

for (i in 1:length(sets)) {
   symbols(sets[[i]][,sq],sets[[i]][,cu],circles=sets[[i]][,num],
   bg=colors[[i]],add=T)
}    

I know you can have a variable evaluated to specify the column (like var="cu"; set1[,var]; I want to know how to get a variable to specify the data.frame itself (and another to evaluate the column).


Update: Ran across this post on r-bloggers which has this example:

x <- 42
eval(parse(text = "x"))
[1] 42

I'm able to do something like this now:

eval(parse(text=paste(set[[1]],"$",var1,sep="")))

In fiddling with this, I'm finding it interesting that the following are not equivalent:

vars <- data.frame("var1","var2")
eval(parse(text=paste(set[[1]],"$",var1,sep="")))
eval(parse(text=paste(set[[1]],"[,vars[[1]]]",sep="")))

I actually have to do this:

eval(parse(text=paste(set[[1]],"[,as.character(vars[[1]])]",sep="")))

Update2: The above works to output values... but not in trying to plot. I can't do:

for (i in 1:length(set)) {
symbols(eval(parse(text=paste(set[[i]],"$",var1,sep=""))),
       eval(parse(text=paste(set[[i]],"$",var2,sep=""))),
       circles=paste(set[[i]],".","circles",sep=""),
       fg="white",bg=colors[[i]],add=T)
}

I get invalid symbol coordinates. I checked the class of set[[1]] and it's a factor. If I do is.numeric(as.numeric(set[[1]])) I get TRUE. Even if I add that above prior to the eval statement, I still get the error. Oddly, though, I can do this:

set.xvars <- as.numeric(eval(parse(text=paste(set[[i]],"$",var1,sep=""))))
set.yvars <- as.numeric(eval(parse(text=paste(set[[i]],"$",var2,sep=""))))
symbols(xvars,yvars,circles=data$var3)

Why different behavior when stored as a variable vs. executed within the symbol function?

Answer

Carl Witthoft picture Carl Witthoft · Jan 30, 2012

You found one answer, i.e. eval(parse()) . You can also investigate do.call() which is often simpler to implement. Keep in mind the useful as.name() tool as well, for converting strings to variable names.