开发者

Convert string to a variable name

I am using R to parse a list of strings in the form:

original_string <开发者_运维问答;- "variable_name=variable_value"

First, I extract the variable name and value from the original string and convert the value to numeric class.

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

Then, I would like to assign the value to a variable with the same name as the parameter_name string.

variable_name <- parameter_value

What is/are the function(s) for doing this?


assign is what you are looking for.

assign("x", 5)

x
[1] 5

but buyer beware.

See R FAQ 7.21 http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-can-I-turn-a-string-into-a-variable_003f


You can use do.call:

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


There is another simple solution found there: http://www.r-bloggers.com/converting-a-string-to-a-variable-name-on-the-fly-and-vice-versa-in-r/

To convert a string to a variable:

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

And the opposite:

x <- 42
deparse(substitute(x))
[1] "x"


The function you are looking for is get():

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

Confirming that the memory address is identical:

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

Reference: R FAQ 7.21 How can I turn a string into a variable?


Use x=as.name("string"). You can use then use x to refer to the variable with name string.

I don't know, if it answers your question correctly.


strsplit to parse your input and, as Greg mentioned, assign to assign the 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()


assign is good, but I have not found a function for referring back to the variable you've created in an automated script. (as.name seems to work the opposite way). More experienced coders will doubtless have a better solution, but this solution works and is slightly humorous perhaps, in that it gets R to write code for itself to execute.

Say I have just assigned value 5 to x (var.name <- "x"; assign(var.name, 5)) and I want to change the value to 6. If I am writing a script and don't know in advance what the variable name (var.name) will be (which seems to be the point of the assign function), I can't simply put x <- 6 because var.name might have been "y". So I do:

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

x will be changed to 6, and if the variable name was anything other than "x", that variable will similarly have been changed to 6.


I was working with this a few days ago, and noticed that sometimes you will need to use the get() function to print the results of your variable. 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

From there, if you try to print the variable varnames[1], it returns 'jan'. To work around this, you need to do print(get(varnames[1]))


If you want to convert string to variable inside body of function, but you want to have variable global:

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

[1] "xxx"


Maybe I didn't understand your problem right, because of the simplicity of your example. To my understanding, you have a series of instructions stored in character vectors, and those instructions are very close to being properly formatted, except that you'd like to cast the right member to numeric.

If my understanding is right, I would like to propose a slightly different approach, that does not rely on splitting your original string, but directly evaluates your instruction (with a little improvement).

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

Basically, what we are doing is that we 'improve' your instruction variable_name="10" so that it becomes variable_name="10" %>% as.numeric, which is an equivalent of variable_name=as.numeric("10") with magrittr pipe-stream syntax. Then we evaluate this expression within current environment.

Hope that helps someone who'd wander around here 8 years later ;-)


Other than assign, one other way to assign value to string named object is to access .GlobalEnv directly.

# Equivalent
assign('abc',3)

.GlobalEnv$'abc' = 3

Accessing .GlobalEnv gives some flexibility, and my use case was assigning values to a string-named list. For example,

.GlobalEnv$'x' = list()
.GlobalEnv$'x'[[2]] = 5 # works

var = 'x'
.GlobalEnv[[glue::glue('{var}')]][[2]] = 5 # programmatic names from glue()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜