2

I have the code:

pos = {2, 3, 5};
tbl = Table[i*j, {i, 6}, {j, 3}];
totRow = Total /@ tbl[[pos]];

which defines some row indices (pos) and a table and some of all rows given by indices pos. However, I would like to do in mathematica way (so probably no fors) sum those rows and replace them by that single total row, which in my example has the name totRow. What is the most effective way. I was thinking succession of drop, join but is there a better way?

To supply an example:

pos = {2, 3, 5};
tbl = Table[i*j, {i, 6}, {j, 3}];
totRow = Total /@ tbl[[pos]];
finTbl = Join[Delete[tbl, Partition[pos, 1]], {totRow}];
totRow
TableForm[tbl]
TableForm[finTbl]

gives an idea, the three rows from tbl at indices given by pos are deleted and the totRow added. So this works but looks clumsy, I am just curious whether there is proper or better way.

UPDATE: I changed the examples so that the original table is made of i*j for better legibility.

atapaka
  • 3,954
  • 13
  • 33
  • I'm a little unclear on this: do you want to replace each of those rows with a copy of totRow? Or do you want to get rid of all of those rows and replace, say, the first with totRow? – march Nov 26 '15 at 03:32
  • Sorry about that, I want to get rid of all the rows indices of which are specified by pos and add the row totRow, so I have the idea of drop + join, but I am wondering whether it can be done compactly and effectively... – atapaka Nov 26 '15 at 03:34
  • I don't understand. Please try to be more explicit – Dr. belisarius Nov 26 '15 at 03:38
  • Right: perhaps an example with the expected output would be helpful. But, perhaps this? Append[Part[tbl, Complement[Range@Length@tbl, pos]], Total[tbl[[pos]], {2}]] – march Nov 26 '15 at 03:39
  • Or Append[Delete[tbl, {#} & /@ pos], Total[tbl[[pos]], {2}]]. – march Nov 26 '15 at 03:49
  • Well, personally I feel the position of totRow quite strange. Why placing it in the last line? Something like tbl[[pos]] = Total /@ tbl[[pos]]; tbl is more intuitive in my opinion. – xzczd Nov 26 '15 at 03:58
  • Append[#1[[Complement[Range@Length@#1, #2]]], Total[#[[#2]], {2}]] &[tbl, pos], where tbl and pos are the table and position list. Edit: Actually, just saw march's comment - that's cleaner... – ciao Nov 26 '15 at 08:42
  • @xzczd your solution is great visually but does not work. First it sums along the rows not columns and second, it produces something like {{1, 2, 3}, 10, 20, {4, 8, 12}, 30, {6, 12, 18}} for the table constructed as tbl = Table[i*j, {i, 6}, {j, 3}];. So it does not insert a single row but rather inserts individual elements of the result into each of the original rows. But it would be great if this approach would work. – atapaka Nov 26 '15 at 15:42
  • Yeah, it doesn't meet your requirement, I just mean I personally think forming such a mixed list isn't a very good idea. – xzczd Nov 26 '15 at 16:10

4 Answers4

4

Answer:

(*Generate table*)
table = Table[RandomReal[], {6}, {3}];

(*Declare positions*)
pos = {2, 3, 5};

(*Carry out addition, removal and modification*)
Append[Delete[table, Partition[pos, 1]], #] &[Total@# &[table[[#]] & /@ pos]]

Reference:
Append
Table
RandomReal
Delete
Partition
Total
@ | /@ | # etc.

e.doroskevic
  • 5,959
  • 1
  • 13
  • 32
1

The way you are doing it seems just fine. If you want to make it less clear what you are doing, and add some shorthand notation you could rewrite it like this:

finTbl = tbl~Delete~Transpose@{pos}~Join~{Total /@ tbl[[pos]]}

(it hurts my brain to try and read code written using infix notation, but I was trying to do it with the smallest number of characters)

Jason B.
  • 68,381
  • 3
  • 139
  • 286
1

As an oneliner. You don't need Table to create a random matrix

Append[Delete@##, Plus @@@ Extract@##] & @@ {RandomReal[1, {6, 3}], List /@ {2, 3, 5}};
eldo
  • 67,911
  • 5
  • 60
  • 168
1
f[table_, pos_] := Append[Delete[table, List /@ pos], Tr /@ table[[pos]]]

finTbl = f[tbl, pos]
Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453