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?

Réponses:



66

Vous pouvez utiliser do.call:

 do.call("<-",list(parameter_name, parameter_value))

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


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?


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

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.


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


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


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"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.