2
$\begingroup$

How can I transform

data = {{1, 0}, {0, 1}, {1, 1}}

to

{{1, f[0]}, {0, f[1]}, {1, f[1]}}


This is similar to Applying a function to the second element of a list and another way to do this mapping of a two argument function, but it's not the same question

$\endgroup$
2
  • 1
    $\begingroup$ MapAt[f, data, {All, -1}] $\endgroup$
    – Kuba
    Jun 30 '16 at 13:02
  • $\begingroup$ This is almost certainly a duplicate isn't it? $\endgroup$
    – march
    Jun 30 '16 at 15:55
3
$\begingroup$
data = {{1, 0}, {0, 1}};
data /. {x_?NumericQ, y_?NumericQ} :> {x, f@y}

and

data = {{1, 0}, {0, 1}};
MapAt[f, data, {All, 2}]

will fix the problems mentioned by masterxilo's answer

$\endgroup$
2
  • $\begingroup$ MapAt[f, data, {All, -1}] works as well. $\endgroup$ Jun 30 '16 at 13:11
  • $\begingroup$ @J.M. yep, I changed that because it was identical to Kuba's comment. $\endgroup$
    – vapor
    Jun 30 '16 at 13:12
3
$\begingroup$
{#1, f@#2} & @@@ data

But we can also generalize MapAt to do the job: Note that

MapAt[f, data, {1, 2}] === {{1, f[0]}, {0, 1}, {1, 1}}

So we can use

MapAtP[f_, expr_, positionPattern_] := MapIndexed[
  If[MatchQ[#2, positionPattern], f@#1, #1] &, expr, Infinity]

MapAtP[f, data, {_, 2}]

Aside

David Wagner's “Power programming with Mathematica”

Are you interested in purchasing David Wagner's "Power programming with Mathematica"?

mentions the following idiom as "a more Mathematica-like way" to transform on the values of a list of (x,y) data points.

data = {{1, 0}, {0, 1}, {1, 1}};
data /. {x_, y_} -> {x, f@y}
(**)
{{1, f[1]}, {0, f[0]}, {1, f[1]}}

But it fails with lists of length exactly 2:

data = {{1, 0}, {0, 1}};
data /. {x_, y_} -> {x, f@y}
(**)
{{1, 0}, f[{1, 0}]}
$\endgroup$
1
  • 2
    $\begingroup$ your replacement rule should be ...f@y $\endgroup$
    – vapor
    Jun 30 '16 at 13:09

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