2
$\begingroup$

This question already has an answer here:

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.

$\endgroup$

marked as duplicate by march, Jens, MarcoB, Mr.Wizard Jul 28 '16 at 18:51

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    $\begingroup$ Something like Replace[m, {b___, x_} -> {b, 2 x}, {1}] ? $\endgroup$ – b.gates.you.know.what Jul 28 '16 at 15:04
  • 2
    $\begingroup$ m[[All, 4]] = 2 * m[[All, 4]] $\endgroup$ – J_Nat Jul 28 '16 at 15:12
  • 1
    $\begingroup$ @J_Nat with your method all I have to do is write m[[All, 4]] = m[[All, 1]]/Total[m[[All, 2]]] . Interesting and amazingly obvious... $\endgroup$ – Tom Zinger Jul 28 '16 at 15:18
  • 1
    $\begingroup$ @TomZinger Glad to be of service :) $\endgroup$ – J_Nat Jul 28 '16 at 15:21
  • 3
    $\begingroup$ Why should this not be considered a duplicate of Elegant operations on matrix rows and columns? $\endgroup$ – Jens Jul 28 '16 at 15:39
1
$\begingroup$

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).

$\endgroup$
  • 1
    $\begingroup$ Or use Append[Most[#], First[#]/total] &. $\endgroup$ – J. M. is away Jul 28 '16 at 15:19
  • 1
    $\begingroup$ Yeah, you can rack up a bunch of equally nice ways for this. It's up to where the OP wants to go, really. $\endgroup$ – Emilio Pisanty Jul 28 '16 at 15:26
2
$\begingroup$

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

$\endgroup$
  • 1
    $\begingroup$ Nice, clean, straight forward answer. Could also use m[[All,4]], etc rather than m[1;;2,4]. $\endgroup$ – Jack LaVigne Jul 29 '16 at 2:08
2
$\begingroup$
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.

$\endgroup$

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