I often have a list of pairs, as
data = {{0,0.0},{1,12.4},{2,14.6},{3,25.1}}
and I want to do something, for instance Rescale
, to all of the second elements without touching the first elements. The neatest way I know is:
Transpose[MapAt[Rescale, Transpose[data], 2]]
There must be a way to do this without so much Transpose
ing. My wish is for something like this to work:
MapAt[Rescale, data, {All, 2}]
But my understanding is that MapAt
takes Position
-style specifications instead of Part
-style specifications. What's the proper solution?
To clarify,
I'm seeking a solution where I don't have to repeat myself, so lacking double Transpose
or double [[All,2]]
, because I consider repetition a signal I'm not doing something the easiest way. However, if eliminating the repetition requires the introduction of intermediate variables or a named function or other additional complexity, maybe the transpose/untranspose solution is already correct.
Use
Part
:Create a copy first if you need to. (
data2 = data
thendata2[[All, 2]]
etc.)Amending my answer to keep up with ruebenko's, this can be made into a function also:
This is quite general is design.
I am coming late to the party, and what I will describe will differ very little with what @Mr. Wizard has, so it is best to consider this answer as a complementary to his solution. My partial excuses are that first, the function below packages things a bit differently and closer to the syntax of
MapAt
itself, second, it is a bit more general and has an option to use withListable
function, and third, I am reproducing my solution from the past Mathgroup thread for exactly this question, which is more than 2 years old, so I am not plagiarizing :)So, here is the function:
This is the same idea as what @Mr. Wizard used, with these differences: 1. In case when the spec is not of the prescribed form, regular
MapAt
will be used automatically 2. Not all functions areListable
. The solution of @Mr.Wizard assumes that either a function isListable
or we want to apply it to the entire list. In the above code, you can specify this by theMappedListable
option.I will also borrow a few examples from my answer in the above-mentioned thread:
Testing on large lists shows that using Listability improves the performance, although not so dramatically here:
This is likely because for the above function (
#/10&
),Map
(which is used internally inmapAt
for theMappedListable->False
(default) setting, was able to auto-compile. In the example below, the difference is more substantial:The point is that, while
f
was not declaredListable
, we know that its body is built out ofListable
functions, and thus it can be applied to the entire list - but OTOH it can not be auto-compiled byMap
. Note that addingListable
attribute tof
would have been completely wrong here and would destroy the purpose, leading tomapAt
being slow in both cases.How about
which returns what you want (ie, it does not alter
data
)If no
Transpose
is allowed,works.
EDIT: As "shortest" is now the goal, best from me so far is:
at 80 characters, which is identical to Mr.Wizard's... So vote for his answer.
Here is another approach:
Edit 1:
An extension from Mr.Wizard, that does not copy it's data.
used like this
Edit 2: Or like this
This worked for me and a friend