Getting strings recognized as variable names in R

倖福魔咒の 提交于 2019-12-27 18:23:14

问题


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?


回答1:


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.




回答2:


The basic answer to the question in the title is eval(as.symbol(variable_name_as_string)) as Josh O'Brien uses. e.g.

var.name = "x"
assign(var.name, 5)
eval(as.symbol(var.name)) # outputs 5

Or more simply:

get(var.name) # 5



回答3:


Without any example data, it really is difficult to know exactly what you are wanting. For instance, I can't at all divine what your object set (or is it sets) looks like.

That said, does the following help at all?

set1 <- data.frame(x = 4:6, y = 6:4, z = c(1, 3, 5))

plot(1:10, type="n")
XX <- "set1"
with(eval(as.symbol(XX)), symbols(x, y, circles = z, add=TRUE))

EDIT:

Now that I see your real task, here is a one-liner that'll do everything you want without requiring any for() loops:

with(dat, symbols(sq, cu, circles = num,
                  bg = c("red", "blue")[(num>5) + 1]))

The one bit of code that may feel odd is the bit specifying the background color. Try out these two lines to see how it works:

c(TRUE, FALSE) + 1
# [1] 2 1
c("red", "blue")[c(F, F, T, T) + 1]
# [1] "red"  "red"  "blue" "blue"



回答4:


If you want to use a string as a variable name, you can use assign:

var1="string_name"

assign(var1, c(5,4,5,6,7))

string_name 

[1] 5 4 5 6 7



回答5:


Subsetting the data and combining them back is unnecessary. So are loops since those operations are vectorized. From your previous edit, I'm guessing you are doing all of this to make bubble plots. If that is correct, perhaps the example below will help you. If this is way off, I can just delete the answer.

library(ggplot2)
# let's look at the included dataset named trees.
# ?trees for a description
data(trees)
ggplot(trees,aes(Height,Volume)) + geom_point(aes(size=Girth))
# Great, now how do we color the bubbles by groups?
# For this example, I'll divide Volume into three groups: lo, med, high
trees$set[trees$Volume<=22.7]="lo"
trees$set[trees$Volume>22.7 & trees$Volume<=45.4]="med"
trees$set[trees$Volume>45.4]="high"

ggplot(trees,aes(Height,Volume,colour=set)) + geom_point(aes(size=Girth))


# Instead of just circles scaled by Girth, let's also change the symbol
ggplot(trees,aes(Height,Volume,colour=set)) + geom_point(aes(size=Girth,pch=set))

# Now let's choose a specific symbol for each set. Full list of symbols at ?pch
trees$symbol[trees$Volume<=22.7]=1
trees$symbol[trees$Volume>22.7 & trees$Volume<=45.4]=2
trees$symbol[trees$Volume>45.4]=3

ggplot(trees,aes(Height,Volume,colour=set)) + geom_point(aes(size=Girth,pch=symbol))



回答6:


What works best for me is using quote() and eval() together.

For example, let's print each column using a for loop:

Columns <- names(dat)
for (i in 1:ncol(dat)){
  dat[, eval(quote(Columns[i]))] %>% print
}


来源:https://stackoverflow.com/questions/9057006/getting-strings-recognized-as-variable-names-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!