Converter string em um nome de variável


100

Estou usando R para analisar uma lista de strings na forma:

original_string <- "variable_name=variable_value"

Primeiro, extraio o nome da variável e o valor da string original e converto o valor em uma classe numérica.

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

Então, eu gostaria de atribuir o valor a uma variável com o mesmo nome da string parameter_name.

variable_name <- parameter_value

Qual é / são a (s) função (ões) para fazer isso?

Respostas:



66

Você pode usar do.call:

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

10
1 para pensar. As pessoas (eu incluído) geralmente esquecem que <-é uma função em si.
Rob,


20

use x=as.name("string") você pode usar then use xpara referir-se à variável com string de nome.

Não sei se responde sua pergunta corretamente


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

18

A função que você está procurando é get():

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

Confirmando que o endereço de memória é idêntico:

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

Referência: R FAQ 7.21 Como posso transformar uma string em uma variável?


1
Ótimo! Esta é a resposta mais concisa que encontrei. Existe uma maneira concisa de fazer o inverso? assim comox <- 42; deparse(substitute(x))
Miao Cai

10

strsplitpara analisar sua entrada e, como Greg mencionou, assignpara atribuir as variáveis.

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

assigné bom, mas não encontrei uma função para fazer referência à variável que você criou em um script automatizado. ( as.nameparece funcionar de maneira oposta). Os programadores mais experientes sem dúvida terão uma solução melhor, mas essa solução funciona e talvez seja um pouco engraçada, pois faz com que R escreva código para ele mesmo executar.

Digamos que acabei de atribuir o valor 5 a x( var.name <- "x"; assign(var.name, 5)) e quero alterar o valor para 6. Se estou escrevendo um script e não sei com antecedência qual será o nome da variável ( var.name) (o que parece ser o ponto do assignfunção), não posso simplesmente colocar x <- 6porque var.namepoderia ter sido "y". Então eu faço:

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

xserá alterado para 6 e, se o nome da variável for diferente "x", essa variável também será alterada para 6.


2

Eu estava trabalhando nisso há alguns dias e percebi que às vezes você precisará usar a get()função para imprimir os resultados da sua variável. ie:

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 daí, se você tentar imprimir a variável varnames[1], ela retornará 'jan'. Para contornar isso, você precisa fazer print(get(varnames[1]))


1

Talvez eu não tenha entendido direito o seu problema, pela simplicidade do seu exemplo. No meu entendimento, você tem uma série de instruções armazenadas em vetores de caracteres e essas instruções estão muito próximas de serem formatadas corretamente, exceto que você gostaria de converter o membro certo para numérico.

Se meu entendimento estiver correto, gostaria de propor uma abordagem um pouco diferente, que não dependa da divisão de sua corda original, mas avalie diretamente sua instrução (com uma pequena melhoria).

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

Basicamente, o que estamos fazendo é que 'melhorar' a sua instrução variable_name="10"para que se torne variable_name="10" %>% as.numeric, o que é um equivalente do variable_name=as.numeric("10")com magrittrsintaxe tubulação-stream. Em seguida, avaliamos essa expressão no ambiente atual.

Espero que ajude alguém que vagou por aqui 8 anos depois ;-)


0

Se você deseja converter string em variável dentro do corpo da função, mas deseja ter uma variável global:

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

[1] "xxx"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.