6
$\begingroup$

I have this list:

a = {{{0, 0}, {1, 7}, {2, 0}, {3, 2}, {4, 7}}, {{0, 0}, {1, 0}, {2, 1}, {3, 2}, {4, 7}}}

and I'd like to transform it to this:

a = {{{0, 0}, {1, 7}, {2, Na}, {3, 2}, {4, 7}}, {{0, 0}, {1, Na}, {2, 1}, {3, 2}, {4, 7}}}

ie I'd like to replace every 0 by Na except in the first sub-sub-list of each sub-list.

All I can come up with is:

Part[#, 2 ;; All, All] & /@ a  /. 0 -> Na

and it works I get

{{{1, 7}, {2, Na}, {3, 2}, {4, 7}}, {{1, Na}, {2, 1}, {3, 2}, {4, 7}}}

but the modification is not attributed to a.

How can I do that?

$\endgroup$
2
  • $\begingroup$ a = Part[#, 2 ;; All, All] & /@ a /. 0 -> Na or perhaps you intended to modify the original copy of a ? $\endgroup$ Commented Jan 8, 2013 at 12:10
  • $\begingroup$ yes I need to modify the original copy of a your solution below works thanks! $\endgroup$
    – Sulli
    Commented Jan 8, 2013 at 12:58

6 Answers 6

5
$\begingroup$

This will work if all your first elements of the sub-lists are of the form {0,0}

a = a /. {{x_?Positive, 0} :> {x, Na}};
a

{{{0, 0}, {1, 7}, {2, Na}, {3, 2}, {4, 7}}, {{0, 0}, {1, Na}, {2, 1}, {3, 2}, {4, 7}}}

$\endgroup$
4
$\begingroup$

This is a good case for ReplaceAt (new in 13.1) and ApplyTo (new in 12.2)

list =
  {{{0, 0}, {1, 7}, {2, 0}, {3, 2}, {4, 7}},
   {{0, 0}, {1, 0}, {2, 1}, {3, 2}, {4, 7}}};

list //= ReplaceAt[{x_, 0} :> {x, Na}, {All, 2 ;;}];

list

{{{0, 0}, {1, 7}, {2, Na}, {3, 2}, {4, 7}}, {{0, 0}, {1, Na}, {2, 1}, {3, 2}, {4, 7}}}

$\endgroup$
3
$\begingroup$

Another quick possibility

a=a/. {n_, r:{_Integer,_Integer}...} :> Join[{n},{ r} /. 0->Na]
$\endgroup$
3
$\begingroup$

Using SubsetMap:

a = {{{0, 0}, {1, 7}, {2, 0}, {3, 2}, {4, 7}}, {{0, 0}, {1, 0}, {2, 
    1}, {3, 2}, {4, 7}}}

SubsetMap[ReplaceAll[0 -> Na], #, 2 ;;] & /@ a

Using MapIndexed:

MapIndexed[If[Last@#2 > 1, ReplaceAll[#1, 0 -> Na], #1] &, a, {2}]

Result:

{{{0, 0}, {1, 7}, {2, Na}, {3, 2}, {4, 7}}, {{0, 0}, {1, Na}, {2,
1}, {3, 2}, {4, 7}}}


WolframLanguageData["SubsetMap", {"VersionIntroduced", 
  "DateIntroduced"}]

enter image description here

$\endgroup$
3
$\begingroup$

Using ReplacePart and Cases as follows:

a = {{{1, 0}, {1, 7}, {2, 0}, {3, 2}, {4, 0}}, 
     {{1, 0}, {1, 0}, {2, 1}, {3, 0}, {4, 7}}, 
     {{1, 0}, {1, 1}, {1, 0}, {3, 1}, {4, 0}}};

patt1 = {x1_, x2_} /; x1 != 0 && x2 == 0;

pos[l_List] := Position[l, patt1]

parts[l_List] := Cases[l, patt1 -> {x1, Na}, 2]

patt2 = Rule[lhs_, rhs_] /; lhs[[2]] != 1;

rep[l_List] := Cases[Thread[pos[#] -> parts[#]] &@l, patt2]

ReplacePart[#, rep[#]] &@a

(*{{{1, 0}, {1, 7}, {2, Na}, {3, 2}, {4, Na}},
   {{1, 0}, {1, Na}, {2, 1}, {3, Na}, {4, 7}},
   {{1, 0}, {1, 1}, {1, Na}, {3, 1}, {4, Na}}}*)
$\endgroup$
2
  • 2
    $\begingroup$ The requirement is to change 0's except in the first element of each sublist. Your solution works if such entries are {0,0}. Can you improve it perhaps? $\endgroup$
    – Syed
    Commented Dec 15, 2023 at 4:01
  • 1
    $\begingroup$ Thanks for pointing out the limitation of the first code, @Syed :-) $\endgroup$ Commented Dec 15, 2023 at 5:05
1
$\begingroup$
a = {
   {{0, 0}, {1, 7}, {2, 0}, {3, 2}, {4, 7}},
   {{0, 0}, {1, 0}, {2, 1}, {3, 2}, {4, 7}}};

Using MapAt and ApplyTo (new in 12.2)

a //= MapAt[ReplaceAll[0 :> Na], {All, 2 ;;}];

a

{{{0, 0}, {1, 7}, {2, Na}, {3, 2}, {4, 7}},
{{0, 0}, {1, Na}, {2, 1}, {3, 2}, {4, 7}}}

$\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.