Re: How do I assign variable names from a list of strings?
- To: mathgroup at smc.vnet.net
- Subject: [mg103035] Re: How do I assign variable names from a list of strings?
- From: Albert Retey <awnl at gmx-topmail.de>
- Date: Fri, 4 Sep 2009 07:01:38 -0400 (EDT)
- References: <h7qep8$11n$1@smc.vnet.net>
Hi, > As a part of a weekly procedure, there are several tsv (tab separated) > files I want to load into Mathematica, process, and then store in a > native format (.dat) for more analysis later on. So far, this is what > I've come up with. > > [1] First I get all the files in the directory data I want to load in > tsvfiles = FileNames["data/*.tsv"]; > tsvfiles > {"data/abx.tsv", "data/aem.tsv", "data/agu.tsv", \ > "data/bmo.tsv", "data/bns.tsv", "data/cm.tsv", "data/cnq.tsv", \ > "data/eca.tsv", "data/g.tsv", "data/imo.tsv", "data/k.tsv", \ > "data/mfc.tsv", "data/pbg.tsv", "data/pot.tsv", "data/ry.tsv", \ > "data/su.tsv", "data/td.tsv", "data/tlm.tsv"} > > [2] I then create names I want for the variables so I can further > process the TSV files and store in native Mathematica format. > varnames = > StringReplace[#, {"data/" -> "px_", ".tsv" -> ""}] & /@ tsvfiles; > > varnames > {"px_abx", "px_aem", "px_agu", "px_bmo", "px_bns", "px_cm", \ > "px_cnq", "px_eca", "px_g", "px_imo", "px_k", "px_mfc", "px_pbg", \ > "px_pot", "px_ry", "px_su", "px_td", "px_tlm"} > > [3] I import an example (this worked!) > data = Import[tsvfiles[[1]], "TSV"]; > Dimensions[data] > {1142, 6} > > [4] Last, I automatically assign the variable name based on the where > I am in the loop. > varnames[[1]] = data; > > So, this is the part I'm not getting right. Is there a way to change > "varnames" into a list of variables I want to assign data to? Or is it > enough to just use the varname[[1]] (for example) as the newly > processed and formatted filename I now want to store? In other words, > storing a variable does not preserve the original name of the variable > when loaded, but rather is re-assigned when imported later on? There are three independent problems with your varnames: 1) the content are strings not symbols, so you cannot assign values to them. 2) the variable names you chose are not valid symbol names in mathematica since they contain a _ which has a special meaning in mathematica and can not be part of a symbol name. 3) the assignment varnames[[1]] will set the first part of the list to data, and not even try to set the value of the content. This has to do with the way Mathematica evaluates expressions: Set has the Attribute HoldFirst. All these problems can be overcome with using more or less sophisticated functions like ToExpression, Symbol, With and Unevaluated but all these have complications which can easily make you struggle with your further coding. Here is something that should work: varnames = Map[ Symbol, (StringReplace[#, {"data/" -> "px$", ".tsv" -> ""}]& /@ tsvfiles) ]; With[{s = varnames[[1]]}, s = data] For cases like that I think it is a much better approach to use DownValues of an extra symbol to hold the data and use that everywhere, e.g.: filecontent[varnames[[1]]] = data; then you can access the data with e.g.: filecontent["px_eca"] or filecontent[varnames[[1]]] everywhere in your code. Actually I would use just the filenames as keys for filecontent which could save you even more coding struggles. And if you use memoization to lazy-load the data only when you need it you will probably have even more fun using your mathematica code in the future, and can achieve all you need with just a one liner: filecontent[fname_String] := filecontent[fname] = Import[fname, "TSV"] with just that definition you can access the content of each file with something like: filecontent["data/tlm.tsv"] or filecontent[tsvfiles[[3]]] and you will only load the data when you actually need it but still keep it in memory in case you need it again. hth, albert