web-dev-qa-db-fra.com

Obtenir des chaînes reconnues comme noms de variables dans R

Connexes: les chaînes comme références de variables dans R
Peut-être lié: Concaténer des expressions pour sous-définir une trame de données


J'ai simplifié la question par la demande de commentaire. Voici quelques exemples de données.

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

Maintenant, je voudrais en faire un graphique à bulles. J'ai un ensemble de données plus compliqué avec plus de 3 couleurs et des sous-ensembles compliqués, mais je fais quelque chose comme ceci:

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

Je voudrais faire une boucle for comme ceci:

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

Je sais que vous pouvez faire évaluer une variable pour spécifier la colonne (comme var="cu"; set1[,var]; Je veux savoir comment obtenir une variable pour spécifier le data.frame lui-même (et une autre pour évaluer la colonne).


Mise à jour: Ran across this post on r-bloggers that has this example:

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

Je peux faire quelque chose comme ça maintenant:

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

En jouant avec cela, je trouve intéressant que les éléments suivants ne soient pas équivalents:

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

En fait, je dois faire ceci:

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

Update2: Ce qui précède fonctionne pour afficher des valeurs ... mais pas pour essayer de tracer. Je ne peux pas faire:

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

Je reçois invalid symbol coordinates. J'ai vérifié la classe de l'ensemble [[1]] et c'est un facteur. Si je fais is.numeric(as.numeric(set[[1]])) j'obtiens TRUE. Même si j'ajoute cela ci-dessus avant l'instruction eval, j'obtiens toujours l'erreur. Curieusement, cependant, je peux le faire:

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)

Pourquoi un comportement différent lorsqu'il est stocké en tant que variable vs exécuté dans la fonction de symbole?

46
Hendy

Vous avez trouvé une réponse, c'est-à-dire eval(parse()). Vous pouvez également rechercher do.call() qui est souvent plus simple à implémenter. Gardez également à l'esprit l'outil as.name() utile pour convertir des chaînes en noms de variables.

34
Carl Witthoft

La réponse de base à la question dans le titre est eval(as.symbol(variable_name_as_string)) comme Josh O'Brien l'utilise. par exemple.

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

Ou plus simplement:

get(var.name) # 5
16
CJB

Sans aucun exemple de données, il est vraiment difficile de savoir exactement ce que vous voulez. Par exemple, je ne peux pas du tout deviner à quoi ressemble votre objet set (ou est-ce sets).

Cela dit, les éléments suivants sont-ils utiles?

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

MODIFIER :

Maintenant que je vois votre vraie tâche, voici un one-liner qui fera tout ce que vous voulez sans nécessiter de boucles for():

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

Le bit de code qui peut sembler étrange est le bit spécifiant la couleur d'arrière-plan. Essayez ces deux lignes pour voir comment cela fonctionne:

c(TRUE, FALSE) + 1
# [1] 2 1
c("red", "blue")[c(F, F, T, T) + 1]
# [1] "red"  "red"  "blue" "blue"
9
Josh O'Brien

Si vous souhaitez utiliser une chaîne comme nom de variable, vous pouvez utiliser assign:

var1="string_name"

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

string_name 

[1] 5 4 5 6 7
8
harris11

Il n'est pas nécessaire de sous-définir les données et de les combiner. Il en va de même pour les boucles puisque ces opérations sont vectorisées. D'après votre montage précédent, je suppose que vous faites tout cela pour créer des graphiques à bulles. Si c'est correct, l'exemple ci-dessous vous aidera peut-être. Si c'est loin, je peux simplement supprimer la réponse.

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

Ce qui fonctionne le mieux pour moi, c'est d'utiliser quote() et eval() ensemble.

Par exemple, imprimons chaque colonne à l'aide d'un for loop:

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