Change entire column of matrix using its own elements for calculations [duplicate]

This question already has an answer here:

Elegant operations on matrix rows and columns

7 answers

I am aware that there are discussions here about multiplying rows or columns in matrices, but I cannot figure out what to do in the following two cases.
I have a matrix, lets say

m = {{1, 2, 3, 4}, {0, 1, 2, 1}}

I want to multiply the last column by 2. What I tried was replace all. Particularly:

m2=m/.{m[[All, 4]] -> 2*m[[All, 4]]}

But unsuccessfully. If I write: m[[All, 4]] -> 2*m[[All, 4]]
I get

{4, 1} -> {8, 2}

but if I use replaceAll (/.) it doesn’t work. If I try to replace a row nevertheless it works fine, for example:

m3 = m /. {m[[2]] -> 2*m[[2]]}

Out: {{1, 2, 3, 4}, {0, 2, 4, 2}}

What I need to do, is actually to replace the last column’s elements with the ratio of the first element of each row over the sum of elements of 2nd column.
I calculate the sum as

Total[m[[All, 2]]]

and I need somehow to create a new matrix that looks like this:

{{1,2,3,1/3},{0,1,2,0}}

But I don’t know how to make the calculation, and repeat it for each row (since my original matrix, not provided in this naive approach has dozens of rows).
Thank you in advance for your help.

=================

=================

3 Answers
3

=================

After the first evaluation is done, the Replace rule you’re trying to apply is actually

{{1, 2, 3, 4}, {0, 1, 2, 1}} /. { {4, 1} -> {8, 2} }

The pattern {4, 1} never occurs in the input, so the rule has no effect. Rows, which do appear explicitly in the initial list, do get replaced.

In general, there’s a huge number of ways to do what you’re asking for, and it sort of depends on exactly where you want to go.

For example, if you just want to double up the last element of the list, then you can take a function that does that, like ({1,1,1,2} #)& (try it on {1,2,3,4}) and then Map it over your list, so

m = {{1, 2, 3, 4}, {0, 1, 2, 1}}
{1,1,1,2}# & /@ m

will do the trick, and it will probably be a very efficient way to get there.

To do the more complicated calculation, you can simply set total = Total[ m[[All,2]] ] and then map

{#[[1]], #[[2]], #[[3]], #[[1]]/total} & /@ m

(where now I need to explicitly build a list from the parts of #, and I need a precomputed total to avoid re-calculating it over and over).

1

 

Or use Append[Most[#], First[#]/total] &.
– J. M.♦
Jul 28 at 15:19

1

 

Yeah, you can rack up a bunch of equally nice ways for this. It’s up to where the OP wants to go, really.
– Emilio Pisanty
Jul 28 at 15:26

You can also use Span to achieve this
m[[1 ;; 2, 4]] = m[[1 ;; 2, 1]]/Total[m[[1 ;; 2, 2]]]

1

 

Nice, clean, straight forward answer. Could also use m[[All,4]], etc rather than m[1;;2,4].
– Jack LaVigne
Jul 29 at 2:08

mat = {{1, 2, 3, 4}, {0, 1, 2, 1}};

With[{sum = Total@mat[[All, 2]]},
mat /. {a_, b__, _} :> {a, b, a/sum}]

Read on patterns and transformation rules in help.