10
$\begingroup$

I've loaded a CSV:

Colors = Import[
  "d:\\bitbucket\\diversity\\data\\nlcd\\nlcd-colors.csv", "CSV"]
{{0., " 0.00000000000 0.00000000000 0.00000000000"}, {11., 
  " 0.27843137255 0.41960784314 0.62745098039"}, {12., 
  " 0.81960784314 0.86666666667 0.97647058824"}, {21., 
  " 0.86666666667 0.78823529412 0.78823529412"}, {22., 
  " 0.84705882353 0.57647058824 0.50980392157"}}

And I would like this:

{{0., RGBColor[0.00000000000,0.00000000000,0.00000000000]}, {11., 
  RGBColor[0.27843137255,0.41960784314,0.62745098039]}, {12., 
  RGBColor[0.81960784314,0.86666666667,0.97647058824]}, {21., 
  RGBColor[0.86666666667,0.78823529412,0.78823529412]}, {22., 
  RGBColor[0.84705882353,0.57647058824,0.50980392157]}}
$\endgroup$
3
  • 1
    $\begingroup$ Flatten[{First[#], RGBColor @@@ ToExpression[StringSplit[Rest[#]]]}] & /@ Colors $\endgroup$ Dec 20, 2017 at 15:03
  • $\begingroup$ {#[[1]], RGBColor @@ (ToExpression /@ StringSplit[#[[2]]])} & /@Colors $\endgroup$
    – k_v
    Dec 20, 2017 at 15:06
  • 6
    $\begingroup$ Or use MapAt: MapAt[RGBColor @@ ToExpression[StringSplit[#]] &, Colors, {All, 2}] $\endgroup$ Dec 20, 2017 at 15:07

5 Answers 5

16
$\begingroup$

Edit

Ok, so an incorrect answer producing arrays like:

{{"0.", RGBColor["0.00000000000", "0.00000000000", "0.00000000000"]}}

received +12 and an accept. Let's correct it though:

Activate @ ReadList[
  file
, {Number, RGBColor[Inactive[ToExpression][Word], Number, Number]}
, WordSeparators -> {"\t", " ", ","}
]
{{0., RGBColor[0., 0., 0.]}, ...}

Original answer

Let's try to get those numbers directly from the file:

ReadList[
  file
, {Word, RGBColor[Word, Word, Word]}
, WordSeparators -> {"\t", " ", ","}
]

To learn what is going on please read:

Can Read[] apply a custom function automatically to the read values?

$\endgroup$
3
  • $\begingroup$ Thanks, for all the answers, I would accept more if I could. $\endgroup$
    – pnz1337
    Dec 20, 2017 at 16:45
  • $\begingroup$ I think your original answer was not the same as the one under Original answer; I did check the original answer and it did work; my up-vote was motivated by the use of ReadList; I think you are onto something though $\endgroup$
    – user42582
    Dec 23, 2017 at 8:04
  • $\begingroup$ @user42582 my very first answer was: {#, RGBColor[##2]} & @@@ ReadList[ file, ConstantArray[Word, 4], WordSeparators -> {"\t", " ", ","}] but I don't think it works like it should. I was too fast and didn't noticed that the result was containing strings instead of numbers. $\endgroup$
    – Kuba
    Dec 23, 2017 at 11:58
10
$\begingroup$

If we define:

rgb[s_] := RGBColor @@ StringReplace[s, Whitespace~~n:NumberString :> ToExpression[n]]

then we can write any of the following expressions:

MapAt[rgb, Colors, {All, 2}]

Colors // Query[All, {2 -> rgb}]

ReplacePart[Colors, {i_, 2} :> rgb[Colors[[i, 2]]]]

to obtain:

result

$\endgroup$
6
$\begingroup$

Here is your list:

lst = {{0., " 0.00000000000 0.00000000000 0.00000000000"}, {11., 
   " 0.27843137255 0.41960784314 0.62745098039"}, {12., 
   " 0.81960784314 0.86666666667 0.97647058824"}, {21., 
   " 0.86666666667 0.78823529412 0.78823529412"}, {22., 
   " 0.84705882353 0.57647058824 0.50980392157"}};

Try this:

{#[[1]], RGBColor[Map[ToExpression, StringSplit[#[[2]]]]]} & /@ lst

(*  {{0., RGBColor[{0., 0., 0.}]}, {11., 
  RGBColor[{0.27843137255, 0.41960784314, 0.62745098039}]}, {12., 
  RGBColor[{0.81960784314, 0.86666666667, 0.97647058824}]}, {21., 
  RGBColor[{0.86666666667, 0.78823529412, 0.78823529412}]}, {22., 
  RGBColor[{0.84705882353, 0.57647058824, 0.50980392157}]}}   *)

enter image description here

Have fun!

$\endgroup$
5
$\begingroup$

You could also try

 MapAt[
   Apply[RGBColor,First@ImportString[#, "Table"]] &, Colors, {All, 2}]

which outputs

 {
   {0., RGBColor[0., 0., 0.]}, 
   {11.,RGBColor[0.27843137255, 0.41960784314, 0.62745098039]}, 
   {12., RGBColor[0.81960784314, 0.86666666667, 0.97647058824]}, 
   {21., RGBColor[0.86666666667, 0.78823529412, 0.78823529412]}, 
   {22., RGBColor[0.84705882353, 0.57647058824, 0.50980392157]}
  }

or, equivalently

enter image description here

Effectively, MapAt
applies an appropriate data extracting function on the second item for every entry in the list Colors.

The function that it uses to extract the data (in this case, the RGB values in the strings) is Apply[RGBColor,First@ImportString[#, "Table"]] &.

Every string sequence of RGB values is first parsed, using ImportString; this produces a list of values (not a string, anymore).

Each list of values is then, in turn, transformed to an RGBColor by replacing their head of List with the appropriate RGBColor head (this is what the Apply[RGBColor,<>] portion of the code does).

$\endgroup$
4
$\begingroup$

This way is quite simple:

{#1, RGBColor[ToExpression /@ StringSplit[#2]]} & @@@ Colors

It is almost the same as k_v's comment except I use #1 and #2 instead of #[[1]] and #[[2]], and I use @@@ instead of @@.

a @@@ b is shorthand for Apply[a, b, {1}], e.g. f @@@ {{a, b}, {c, d}} gives {f[a, b], f[c, d]}.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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