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()
Related
Is there a function in Lua to generate a variable name with a string and a value?
For example, I have the first (string) part "vari" and the second (value) part, which can vary. So I want to generate "vari1", "vari2", "vari3" and so on. Something like this:
"vari"..value = 42 should then be vari1 = 42.
Thanks
Yes, but it most likely is a bad idea (and this very much seems to be an XY-problem to me). If you need an enumerated "list" of variables, just use a table:
local var = { 42, 100, 30 }
var[4] = 33 -- add a fourth variable
print(var[1]) -- prints 42
if you really need to set a bunch of variables though (perhaps to adhere to some odd API?), I'd recommend using ("..."):format(...) to ensure that your variables will be formatted as var<int> rather than var1.0, var1e3 or the like.
Th environment in Lua - both the global environment _G and the environment of your script _ENV (in Lua 5.2), which usually is the global environment, are just tables in the end, so you can write to them and read from them the same way you'd write to and read from tables:
for value = 1, 3 do
_ENV[("vari%d"):format(value)] = value^2
end
print(var3) -- prints 3*3 = 9
-- verbose ways of accessing var3:
print(_ENV.var3) -- still 9
print(_ENV["var"]) -- 9 as well
Note that this is most likely just pollution of your script environment (likely global pollution) which is considered a bad practice (and often bad for performance). Please outline your actual problem and consider using the list approach.
Yes. Call:
rawset(table, key, value)
Example:
rawset(_G, 'foo', 'bar')
print(foo)
-- Output: bar
-- Lets loop it and rawget() it too
-- rawset() returns table _G here to rawget()
-- rawset() is executed before rawget() in this case
for i = 1, 10 do
print(rawget(rawset(_G, 'var' .. i, i), 'var' .. i))
end
-- Output: 10 lines - First the number 1 and last the number 10
See: https://lua.org/manual/5.1/manual.html#pdf-rawset
Putting all together and create an own function...
function create_vars(var, start, stop)
for i = start, stop do
print(var .. i, '=>', rawget(rawset(_G, var .. i, i), var .. i))
end
end
And use it...
> create_vars('var', 42, 42)
var42 => 42
> print(var42)
42
The title may sound a bit weird, but the situation is not so much.
I have some lists.
Here they are initialized (global variables):
sensor0, sensor1, sensor2, sensor3 = ([] for i in range(4))
Now we have a variable that indicates the list that i can insert data to. Let's say it's selector = 3.
This means i should append() my value to the sensor3 list.
What is the most practical way to do this in python?
If it was a C style language, i would use a switch-case.
But there is no switch-case syntax in python. Of course i could do multiple ifs, but this seems not the best way to do it.
I wonder, since there is only one letter to the lists that change everytime, perhaps there is a better way to select the proper list to append() to, based on the selector variable.
For your specific case, use eval
sensor0, sensor1, sensor2, sensor3 = ([] for i in range(4))
sensor3 = 20
selector =3
result = eval("sensor"+str(selector))
print(result)
But using a list may be a better option.
Using List
sensor = [[] for i in range(4)]
selector = 3
sensor[selector] = 20
print(sensor[selector])
I'm using Sphinx::Search.
Is there is a easier way for this code example to convert a string to a constant?
use Sphinx::Search;
my $config = {
x => 'SPH_MATCH_EXTENDED2',
};
my $x = $config->{x};
print Sphinx::Search->$x(); # output: 6
I have used advice from
How do I access a constant in Perl whose name is contained in a variable?
and this example works, but if I am always using a string from a hash then do I need to put it into a separate variable to use it in this way?
my $x = $config->{x};
print Sphinx::Search->$x(); # output: 6
Is there a one- liner for this?
# does not work
print Sphinx::Search->$config->{x}();
You can create a reference to the value and immediately dereference it:
Sphinx::Search->${ \$config->{x} };
(If there are no arguments, the () is optional).
I'm guessing that SPH_MATCH_EXTENDED2 is the name of a constant that is exported by Sphinx::Search. The problem is that these are implemented as a subroutine with no parameters, so you may use them only where a bare subroutine name will be understood by Perl as a call, or where an explicit call is valid ( SPH_MATCH_EXTENDED2() )
The easiest solution is to avoid quoting the hash value at all, like so
my $config = { x => SPH_MATCH_EXTENDED2 }
and afterwards, you may use just
$config->{x}; # 6
instead of calling a pseudo class method
Let's assume that I want to create 10 variables which would look like this:
x1 = 1;
x2 = 2;
x3 = 3;
x4 = 4;
.
.
xi = i;
This is a simplified version of what I'm intending to do. Basically I just want so save code lines by creating these variables in an automated way. Is there the possibility to construct a variable name in Matlab? The pattern in my example would be ["x", num2str(i)]. But I cant find a way to create a variable with that name.
You can do it with eval but you really should not
eval(['x', num2str(i), ' = ', num2str(i)]); %//Not recommended
Rather use a cell array:
x{i} = i
I also strongly advise using a cell array or a struct for such cases. I think it will even give you some performance boost.
If you really need to do so Dan told how to. But I would also like to point to the genvarname function. It will make sure your string is a valid variable name.
EDIT: genvarname is part of core matlab and not of the statistics toolbox
for k=1:10
assignin('base', ['x' num2str(k)], k)
end
Although it is long overdue, i justed wanted to add another answer.
the function genvarname is exactly for these cases
and if you use it with a tmp structure array you do not need the eval cmd
the example 4 from this link is how to do it http://www.mathworks.co.uk/help/matlab/ref/genvarname.html
for k = 1:5
t = clock;
pause(uint8(rand * 10));
v = genvarname('time_elapsed', who);
eval([v ' = etime(clock,t)'])
end
all the best
eyal
If anyone else is interested, the correct syntax from Dan's answer would be:
eval(['x', num2str(i), ' = ', num2str(i)]);
My question already contained the wrong syntax, so it's my fault.
I needed something like this since you cannot reference structs (or cell arrays I presume) from workspace in Simulink blocks if you want to be able to change them during the simulation.
Anyway, for me this worked best
assignin('base',['string' 'parts'],values);
I've got a variable that could be a number of types - sometimes it's a string, sometimes a number, table or bool. I'm trying to print out the value of the variable each time like this:
print("v: "..v)
with v being my variable. Problem is, when I get a value that can't be concatenated I get this error:
myscript.lua:79: attempt to concatenate a table value
I've tried changing it to this in case it manages to detect whether or not the variable can be printed:
print("v: "..(v or "<can't be printed>"))
but I had the same problem there. Is there some sort of function I can use to determine if a variable can be concatenated to a string, or a better way of printing out variables?
You can provide the values as separate arguments to print:
print("v:", v)
This would print something like
v: table: 006CE900
Not necessarily the most useful, but better than a crash if it's just for debugging purposes.
See here for information on more useful table printing.
tostring(v) works for all possible v values (including nil). So writing your line as:
print( "v: " .. tostring( v ) )
will always work.
Alternatively you could have a look at type( v ) and if its "string" print it, otherwise print something else (if that's what you want).