在R中将字符串识别为变量名

时间:2012-01-29 21:32:51

标签: r variables string-concatenation

相关:Strings as variable references in R
可能相关:Concatenate expressions to subset a dataframe


我根据评论请求简化了问题。这里有一些示例数据。

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

现在,我想从这些中制作一个泡泡图。我有一个更复杂的数据集,有3种颜色和复杂的子集,但我这样做:

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

我想像这样做一个for循环:

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)
}    

我知道你可以评估一个变量来指定列(比如var="cu"; set1[,var];我想知道如何获取一个变量来指定data.frame本身(以及另一个来评估列)。


更新:对于有此示例的r-bloggers,请this post

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

我现在可以做这样的事情:

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

在摆弄这个问题时,我觉得有趣的是以下内容并不等同:

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

我实际上必须这样做:

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

Update2:上述方法可以输出值...但不是尝试绘图。我不能这样做:

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)
}

我得到invalid symbol coordinates。我检查了set [[1]]的类,这是一个因素。如果我is.numeric(as.numeric(set[[1]])),我会TRUE。即使我在eval语句之前添加了上述内容,我仍然会收到错误。奇怪的是,我可以做到这一点:

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)

为什么在符号函数中存储为变量与执行时的行为不同?

6 个答案:

答案 0 :(得分:33)

您找到了一个答案,即eval(parse())。您还可以调查do.call(),这通常更容易实现。请记住有用的as.name()工具,用于将字符串转换为变量名称。

答案 1 :(得分:14)

标题中问题的基本答案是eval(as.symbol(variable_name_as_string)),因为Josh O&#39; Brien使用。 e.g。

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

或更简单:

get(var.name) # 5

答案 2 :(得分:8)

如果没有任何示例数据,确实很难知道完全你想要什么。例如,我完全不能理解您的对象set(或者sets)的样子。

那说,有以下帮助吗?

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))

修改

现在,我看到了你真正的任务,这里是一个单行程,可以做你想做的一切而不需要任何for()循环:

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

可能感觉奇怪的一位代码是指定背景颜色的位。试试这两行,看看它是如何工作的:

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

答案 3 :(得分:8)

如果要将字符串用作变量名,可以使用assign:

var1="string_name"

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

string_name 

[1] 5 4 5 6 7

答案 4 :(得分:3)

不需要对数据进行子集并将它们组合回来。循环也是如此,因为这些操作是矢量化的。从你之前的编辑,我猜你正在做所有这些来制作泡泡图。如果这是正确的,也许以下示例将对您有所帮助。如果这样的话,我可以删除答案。

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))

答案 5 :(得分:0)

最适合我的是同​​时使用quote()eval()

例如,让我们使用for loop打印每一列:

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