# Replace values of a list containing words and numbers

I'm trying to import some data in a .txt file which contains numbers and words. I import a list which consists of four rows of measured data acquired with an oscilloscope, but the acquisition program puts units in every measured value. Here's an example:

data={{-1.1000u s,-120.00m V,-1.1000u s,8.0000 V},
{-1.0800u s,-120.00m V,-1.0800u s,8.0000 V},
{-60.000n s,-40.000m V,-60.000n s,8.0000 V},
{-40.000n s,-40.000m V,-40.000n s,8.0000 V},
{-20.000n s,-32.000m V,-20.000n s,8.0000 V},
{0.0000 s,-32.000m V,0.0000 s,8.0000 V}}


I would like to know if there's any way I can turn the above list into something more like this:

newdata={{-1.1000,-0.12000,-1.1000,8.0000},
{-0.060000,-0.040000,-0.060000,8.0000},
{-0.040000,-0.040.000,-0.040000,8.0000},
{-0.020000,-0.032000,-0.020.000,8.0000},
{0.0000,-0.032000,0.0000,8.0000}}


I'll appreciate any ideas. Thanks.

-
Try Map[First[Cases[{#}, _?NumericQ, Infinity]] &, data, {2}]. – J. M. Sep 21 '12 at 16:02
Are the u, s, etc strings or symbols? – R. M. Sep 21 '12 at 16:16
@R.M I'm not really sure of that. I import the file as Table. Is there any way to find out? – Juan Sep 21 '12 at 20:28
Can you post a snippet from your actual imported table? If it is a string, it will have quote marks surrounding it when you paste it here (but it won't be displayed in the notebook) – R. M. Sep 21 '12 at 21:07
{"24.940u s", "-72.000m V", "24.940u s", "-8.0000 V"}. Like that? The actual table is too long, 2000 rows more or less. – Juan Sep 21 '12 at 21:11

Your data consist of lists of lists, each of which contains strings of the form:

list = {"24.940u s", "-72.000m V", "24.940u s", "-8.0000 V"};


To convert it to the format you desire, you need to:

• Identify the numeric portion in the string and convert it to a number
• Grab the conversion units (u, m, n, etc.) and apply a suitable rule.

The following function does that (it should be easy to follow what it does based on the above points).

convertList[l : {__String}] :=
With[{rules = {"u" -> 1, "m" -> 10^-3, "n" -> 10^-3, " " -> 1}},
StringCases[l, x : NumberString ~~ s : WordCharacter | WhitespaceCharacter :>
ToExpression@x (s /. rules)]] // Flatten

convertList[list]
(* {24.94, -0.072, 24.94, -8.} *)


Now to do this on the entire data set that you've provided, you have to map it across all the lists (or make it Listable) as:

data = Import["/path/to/the/file.txt", "Data"];
convertList /@ data

-
Awesome! Thank you very much!!! – Juan Sep 21 '12 at 23:45

Something like :

Modify as appropriate the list of rules

unitRules = {m -> 10^-3, u -> 10^-6, n -> 10^-9};

data /. unitRules  /. Times[b___, x_?NumericQ, a___] -> x

(* {{-1.1*10^-6, -0.12, -1.1*10^-6, 8.},
{-1.08*10^-6, -0.12, -1.08*10^-6, 8.},
{-6.*10^-8, -0.04, -6.*10^-8, 8.},
{-4.*10^-8, -0.04, -4.*10^-8, 8.},
{-2.*10^-8, -0.032, -2.*10^-8, 8.},
{0., -0.032, 0., 8.}} *)

-
Thanks. I tried that with my table and it didn't work, though it certainly does with the one I posted. Do you know why could it be? The table I'm working with has the same format, but it's much bigger. – Juan Sep 21 '12 at 20:30
@Juan Can you upload a small sample from your actual file somewhere ? – b.gatessucks Sep 21 '12 at 21:42
link – Juan Sep 21 '12 at 21:52
@Juan R.M provided the unbeatable answer. – b.gatessucks Sep 22 '12 at 7:07

Also

ToExpression /@  StringReplace[ToString /@ #, {"u" -> " 1", "m" | "n" -> " .001"}] & /@
Import["c:\\yourfile", {"Table"}][[All, {1, 3, 5, 7}]]

(* {{-25., -0.08, -25., -8.}, {-24.98, -0.08, -24.98, -8.}, ....}} *)

-
+1 I would have gone with something of the sort. Btw ToExpression is also Listable – Rojolalalalalalalalalalalalala Sep 22 '12 at 15:44