3
$\begingroup$

I have a lot of strings, which have simple nomenclature of number-unit associations and am looking to extract the number according to the units. For example:

d = {"sam1_80.mV_500nm", "sam1_trial2_450nm_300.mV", "sam2_1.1V_6mum"};

Which displays information for 2 samples, which have either mV or V voltages, and lengths with units of nm or mum, which I wish to sort according to the units and combine into a table with rows {Sample,Voltage,Length}. I can get something which does this:

{StringCases[#, "sam" ~~ (x : NumberString) :> ToExpression[x]], 
StringCases[#, (x : NumberString) ~~ "mV" :> 
    ToExpression[x]] /. {} -> 
   0 + StringCases[#, (x : NumberString) ~~ "V" :> 
      ToExpression[x]*1000] /. {} -> 0, 
StringCases[#, (x : NumberString) ~~ "nm" :> 
    ToExpression[x]] /. {} -> 
   0 + StringCases[#, (x : NumberString) ~~ "mum" :> 
      ToExpression[x]*1000] /. {} -> 0}[[All, 1]] & /@ d


out:{{1,80.,500},{1,300.,450},{2,1100.,6000}}

However, this seems very messy to me, and I'm wondering if there's a more elegant/simple form.

$\endgroup$
2
$\begingroup$
{"sample", "voltage", "length"} /. StringCases[
  d,
  Flatten @ {
    "sam" ~~ sn : NumberString :> ("sample" -> ToExpression[sn]),
    m : (NumberString ~~ LetterCharacter ... ~~ #2) :> (# -> QuantityMagnitude[m, #3]) & @@@ {
      {"voltage", "V", "mV"}, {"length", "m", "nm"}}(*name - base unit - final unit*)
    }
  ]

{{1, 80.0, 500}, {1, 300.0, 450}, {2, 1.10*10^3, 6000}}

$\endgroup$
1
$\begingroup$

You could use Interpreter to extract the quantities with the units preserved.

Interpreter["Quantity"] /@ Take[#, -2] & @ StringSplit[#, "_"] & /@ d

InputForm @ %
(*
{{Quantity[80., "Millivolts"], Quantity[500, "Nanometers"]}, 
{Quantity[450, "Nanometers"], Quantity[300., "Millivolts"]}, 
{Quantity[1.1, "Volts"], Quantity[6, "Micrometers"]}}
*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.