Convertir cadena en un nombre de variable

100

Estoy usando R para analizar una lista de cadenas en el formulario:

original_string <- "variable_name=variable_value"

Primero, extraigo el nombre y el valor de la variable de la cadena original y convierto el valor en una clase numérica.

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

Luego, me gustaría asignar el valor a una variable con el mismo nombre que la cadena parameter_name.

variable_name <- parameter_value

¿Cuáles son las funciones para hacer esto?

KnowledgeBone
fuente

Respuestas:

66

Puede usar do.call:

 do.call("<-",list(parameter_name, parameter_value))
Wojciech Sobala
fuente
10
+1 por pensar. La gente (yo incluido) suele olvidar que <-es una función en sí misma.
Rob
20

use x=as.name("string") que puede usar y luego use xpara referirse a la variable con el nombre cadena.

No sé si responde tu pregunta correctamente.

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

La función que busca es get():

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

Confirmando que la dirección de la memoria es idéntica:

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

Referencia: R FAQ 7.21 ¿Cómo puedo convertir una cadena en una variable?

Jozef Janočko
fuente
1
¡Excelente! Esta es la respuesta más concisa que encontré. ¿Existe una forma igualmente concisa de hacer lo contrario? al igual quex <- 42; deparse(substitute(x))
Miao Cai
10

strsplitpara analizar su entrada y, como Greg mencionó, assignpara asignar las 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()
Richie algodón
fuente
5

assignes bueno, pero no he encontrado una función para hacer referencia a la variable que ha creado en un script automatizado. ( as.nameparece funcionar al revés). Los programadores más experimentados sin duda tendrán una mejor solución, pero esta solución funciona y quizás sea un poco graciosa, ya que hace que R escriba código para que lo ejecute.

Digamos que acabo de asignar el valor 5 a x( var.name <- "x"; assign(var.name, 5)) y quiero cambiar el valor a 6. Si estoy escribiendo un script y no sé de antemano cuál var.nameserá el nombre de la variable ( ) (que parece ser el punto del assignfunción), no puedo decir simplemente x <- 6porque var.namepodría haber sido "y". Así que hago:

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

xse cambiará a 6, y si el nombre de la variable era diferente a "x", esa variable se habrá cambiado de manera similar a 6.

CJB
fuente
2

Estuve trabajando con esto hace unos días y noté que a veces necesitará usar la get()función para imprimir los resultados de su variable. es decir:

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

A partir de ahí, si intenta imprimir la variable varnames[1], devuelve 'jan'. Para solucionar esto, debe hacer print(get(varnames[1]))

eigenfoo
fuente
1

Quizás no entendí bien tu problema, debido a la simplicidad de tu ejemplo. A mi entender, tiene una serie de instrucciones almacenadas en vectores de caracteres, y esas instrucciones están muy cerca de estar formateadas correctamente, excepto que le gustaría convertir el miembro correcto en numérico.

Si mi entendimiento es correcto, me gustaría proponer un enfoque ligeramente diferente, que no se basa en dividir su cadena original, sino que evalúa directamente su instrucción (con una pequeña mejora).

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

Básicamente, lo que estamos haciendo es "mejorar" su instrucción variable_name="10"para que se convierta en variable_name="10" %>% as.numeric, lo que es un equivalente variable_name=as.numeric("10")a la magrittrsintaxis de flujo continuo. Luego evaluamos esta expresión dentro del entorno actual.

Espero que ayude a alguien que paseara por aquí 8 años después ;-)

Vongo
fuente
0

Si desea convertir una cadena en una variable dentro del cuerpo de la función, pero desea tener una variable global:

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

[1] "xxx"
Adam Borkowski
fuente