Convertir la chaîne en un nom de variable

100

J'utilise R pour analyser une liste de chaînes sous la forme:

original_string <- "variable_name=variable_value"

Tout d'abord, j'extrais le nom et la valeur de la variable de la chaîne d'origine et convertis la valeur en classe numérique.

parameter_value <- as.numeric("variable_value")
parameter_name <- "variable_name"

Ensuite, je voudrais attribuer la valeur à une variable avec le même nom que la chaîne nom_paramètre.

variable_name <- parameter_value

Quelle est / sont la (les) fonction (s) pour faire cela?

KnowledgeBone
la source

Réponses:

66

Vous pouvez utiliser do.call:

 do.call("<-",list(parameter_name, parameter_value))
Wojciech Sobala
la source
10
+1 pour réfléchir. Les gens (moi y compris) oublient généralement que <-c'est une fonction en soi.
Rob
20

utiliser x=as.name("string") vous pouvez utiliser puis utiliser xpour faire référence à la variable avec la chaîne de nom.

Je ne sais pas si ça répond correctement à ta question

saiteja
la source
2
x=as.symbol("string")
Enrique Pérez Herrero
18

La fonction que vous recherchez est get():

assign ("abc",5)
get("abc")

Confirmer que l'adresse mémoire est identique:

getabc <- get("abc")
pryr::address(abc) == pryr::address(getabc)
# [1] TRUE

Référence: R FAQ 7.21 Comment puis-je transformer une chaîne en variable?

Jozef Janočko
la source
1
Génial! C'est la réponse la plus concise que j'ai trouvée. Existe-t-il une manière tout aussi concise de faire l'inverse? juste commex <- 42; deparse(substitute(x))
Miao Cai
10

strsplitpour analyser votre entrée et, comme Greg l'a mentionné, assignpour affecter les variables.

original_string <- c("x=123", "y=456")
pairs <- strsplit(original_string, "=")
lapply(pairs, function(x) assign(x[1], as.numeric(x[2]), envir = globalenv()))
ls()
Coton Richie
la source
5

assignc'est bien, mais je n'ai pas trouvé de fonction pour renvoyer à la variable que vous avez créée dans un script automatisé. ( as.namesemble fonctionner dans le sens inverse). Les codeurs plus expérimentés auront sans aucun doute une meilleure solution, mais cette solution fonctionne et est peut-être un peu humoristique, en ce sens qu'elle oblige R à écrire du code pour lui-même à exécuter.

Disons que je viens d'attribuer la valeur 5 à x( var.name <- "x"; assign(var.name, 5)) et que je veux changer la valeur en 6. Si j'écris un script et que je ne sais pas à l'avance quel sera le nom de la variable ( var.name) (ce qui semble être le point du assignfonction), je ne peux pas simplement mettre x <- 6parce que cela var.nameaurait pu être "y". Moi aussi:

var.name <- "x"
#some other code...
assign(var.name, 5)
#some more code...

#write a script file (1 line in this case) that works with whatever variable name
write(paste0(var.name, " <- 6"), "tmp.R")
#source that script file
source("tmp.R")
#remove the script file for tidiness
file.remove("tmp.R")

xsera changé en 6, et si le nom de la variable était autre chose que "x", cette variable aura également été changée en 6.

CJB
la source
2

Je travaillais avec cela il y a quelques jours et j'ai remarqué que parfois vous devrez utiliser la get()fonction pour imprimer les résultats de votre variable. c'est à dire :

varnames = c('jan', 'feb', 'march')
file_names = list_files('path to multiple csv files saved on drive')
assign(varnames[1], read.csv(file_names[1]) # This will assign the variable

À partir de là, si vous essayez d'imprimer la variable varnames[1], elle renvoie «jan». Pour contourner ce problème, vous devez faire print(get(varnames[1]))

eigenfoo
la source
1

Peut-être que je n'ai pas bien compris votre problème, à cause de la simplicité de votre exemple. À ma connaissance, vous avez une série d'instructions stockées dans des vecteurs de caractères, et ces instructions sont très proches d'être correctement formatées, sauf que vous souhaitez convertir le bon membre en numérique.

Si je comprends bien, je voudrais proposer une approche légèrement différente, qui ne repose pas sur le fractionnement de votre chaîne d'origine, mais évalue directement votre instruction (avec une petite amélioration).

original_string <- "variable_name=\"10\"" # Your original instruction, but with an actual numeric on the right, stored as character.
library(magrittr) # Or library(tidyverse), but it seems a bit overkilled if the point is just to import pipe-stream operator
eval(parse(text=paste(eval(original_string), "%>% as.numeric")))
print(variable_name)
#[1] 10

Fondamentalement, ce que nous faisons, c'est que nous «améliorons» votre instruction variable_name="10"pour qu'elle le devienne variable_name="10" %>% as.numeric, ce qui équivaut variable_name=as.numeric("10")à la magrittrsyntaxe du flux de tuyaux. Ensuite, nous évaluons cette expression dans l'environnement actuel.

J'espère que cela aidera quelqu'un qui errerait ici 8 ans plus tard ;-)

Vongo
la source
0

Si vous souhaitez convertir une chaîne en variable dans le corps de la fonction, mais que vous souhaitez avoir une variable globale:

test <- function() {
do.call("<<-",list("vartest","xxx"))
}
test()
vartest

[1] "xxx"
Adam Borkowski
la source