# How do you programatically load data into symbols?

I am trying to convert a list of string names into symbols, which will then be used to store data. I have 24 files (where the name of each file is a member of the list mentioned above) that I need to process, which is why I am trying to accomplish my goal progammatically. The code below results in a Tag warning. I have read the normal documentation sources, and appreciate that you can not inappropriately assign something to a protected symbol, but this doesn't help me solve the problem.

Would you have any advice how to accomplish my goal?

Table[(ToExpression[mmsignalnames[[i]]] =
Extract[ToExpression[celfilenames[[i]]], mmammindices[[j]]]), {i,
1, Length[mmsignalnames]}, {j, 1, Length[mmammindices]}]

Set::write: Tag ToExpression in ToExpression[mmsignalGSM356796] is Protected. >>

-
Creating many different symbols is an error-prone practice, because you need ways to manage them, which is hard in this case. What you seem to be needing is a hash-table, with keys being your names (as strings) - this is the second suggestion in the answer of @Mr.Wizard. –  Leonid Shifrin Jan 26 '12 at 23:19
Hello Todd and welcome to the Mathematica StackExchange. Don't forget to upvote good answers (and other people's questions) using the triangle above the number next to the post, and use the checkmark to "accept" the answer to your question that you think best answers it. You now have enough "reputation" (points) to visit the chat room and chat if you would like. –  Sjoerd C. de Vries Jan 26 '12 at 23:20

One solution is to use the third argument of ToExpression:

With minimal modification, a working version of your code would look like this:

Table[
ToExpression[
mmsignalnames[[i]],
InputForm,
Function[name,
name = Extract[ToExpression[celfilenames[[i]]], mmammindices[[j]]],
HoldAll]],
{i, Length[mmsignalnames]}, {j, Length[mmammindices]}]


(Untested because I don't have your data; but see below for the main idea and a small demonstration.)

The core of the method is this:

ToExpression["a", InputForm, Function[name, name = 1, HoldAll]]


ToExpression will wrap the result into its third argument before evaluating it. We can make the third argument a function that sets a value to the symbol (in this simple example it always sets the value to 1). HoldAll is needed to make sure the symbol won't evaluate when it is passed to the function.

You might find all the evaluation control I'm using here a bit confusing. To learn how to work with unevaluated expressions, I recommend reading

It is one of the best tutorials on the matter.

Finally, after answering your actual question, I'd like to suggest you use a hash table instead of symbols:

Instead of creating symbols from the strings "a", "b", "c", ..., and assigning to them, you could assign to myTable["a"], myTable["b"], ... This will make programmatic access to this data trivial. You won't need to bother with evaluation control nearly as much. And more importantly, you can avoid accidental name collisions with existing symbols. Here's an example:

(myTable[#] = 1) & /@ {"a", "b", "c"}

-

You need to make the left-hand side of Set a symbol at the time of evaluation. Use With or similar to inject the symbol:

mmsignalnames = {"one", "two", "three"};

With[{lhs = ToExpression[mmsignalnames[[2]]]},
lhs = 5
];

two

5


Another approach that could be important if you are trying to make assignments to symbols that already have values is this:

Function[{lhs}, lhs = 7, HoldAll] @@ MakeExpression[ mmsignalnames[[2]] ] ;

two

7


Also, it bears mentioning that one may also use indexed symbols such as

name["two"] = 5;

name["two"]

5

-
In the first case when you know your symbols haven't been defined yet, you could shorten it with Evaluate[ToExpression[mmsignalnames[[2]]]]=5 –  Rojo Jan 27 '12 at 15:51
@Rojo yes, you can; I think that With is more flexible however, and I thought it would be easier to use in practice, though I admit I did not actually try it both ways (I would prefer indexed symbols myself). –  Mr.Wizard Jan 28 '12 at 1:58