Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplify apply, sapply apply expression on list of matrices

Tags:

r

sapply

I want to find maximum in both columns [,1] and [,2] accross all numbers in this data structure:

[[1]]
[[1]][[1]]
          [,1]    [,2]
 [1,] 382000.5 4633934
 [2,] 381974.0 4633981
 [3,] 381963.1 4634012
...

[[2]]
[[2]][[1]]
          [,1]    [,2]
 [1,] 382140.5 4634271
 [2,] 382185.2 4634325
 [3,] 382235.3 4634367
...

[[3]]
[[3]][[1]]
          [,1]    [,2]
 [1,] 382536.0 4634631
 [2,] 382595.6 4634683
 [3,] 382628.1 4634715
....

This is my solution:

> apply(sapply(x, function (x) apply(x[[1]], 2, max)), 1, max)
[1]  383581.5 4635506.3

Can this ugly expression be further simplified? It should be, it is just a simple maximum over all numbers in data structure.

Data dump of x:

> dput(x)
list(list(structure(c(382000.457880439, 381973.953198931, 381963.118550682, 
381949.575240371, 381949.575240371, 381952.283902433, 381963.118550682, 
381972.5988679, 381995.622495429, 382020.00045399, 382032.18943327, 
382028.126440176, 382024.063447083, 382025.417778114, 382052.504398737, 
382083.654012453, 382140.535915761, 4633933.72335068, 4633981.3471317, 
4634012.49674542, 4634050.41801429, 4634061.25266254, 4634082.92195904, 
4634099.17393141, 4634118.13456585, 4634127.61488307, 4634130.32354513, 
4634142.51252441, 4634166.89048297, 4634193.97710359, 4634210.22907597, 
4634231.89837247, 4634245.44168278, 4634271.17397237), .Dim = c(17L, 
2L))), list(structure(c(382140.535915761, 382185.228839788, 382235.33908794, 
382290.866660217, 382331.496591151, 382370.772191054, 382405.984797864, 
382427.654094362, 382453.386383953, 382473.70134942, 382536.000576853, 
4634271.17397237, 4634325.34721361, 4634367.33147558, 4634416.0873927, 
4634454.00866157, 4634494.63859251, 4634527.14253725, 4634556.93781994, 
4634577.25278541, 4634592.15042675, 4634631.42602665), .Dim = c(11L, 
2L))), list(structure(c(382536.000576853, 382595.591142223, 382628.09508697, 
382636.221073157, 382645.701390375, 382660.599031717, 382667.370686873, 
382672.788010998, 382702.583293682, 382737.795900492, 382782.48882452, 
382791.969141738, 382814.992769267, 382844.788051952, 382862.394355357, 
382870.520341543, 4634631.42602665, 4634682.89060583, 4634715.39455058, 
4634747.89849533, 4634773.63078492, 4634787.17409523, 4634819.67803998, 
4634854.89064679, 4634888.74892257, 4634915.83554319, 4634955.11114309, 
4634960.52846722, 4634964.59146031, 4634983.55209475, 4634991.67808093, 
4634991.67808093), .Dim = c(16L, 2L))), list(structure(c(382862.394355357, 
382911.150272478, 382935.528231038, 382957.197527536, 382972.095168879, 
382993.764465377, 383014.079430844, 383058.772354871, 383085.858975494, 
383104.81960993, 383121.071582304, 383138.677885709, 383149.512533958, 
383165.764506331, 383184.725140767, 383210.457430359, 383233.481057888, 
383240.252713044, 383248.378699231, 4634991.67808093, 4635030.95368084, 
4635060.74896352, 4635082.41826002, 4635104.08755652, 4635139.30016333, 
4635152.84347364, 4635167.74111498, 4635178.57576323, 4635185.34741839, 
4635185.34741839, 4635185.34741839, 4635186.70174942, 4635181.28442529, 
4635171.80410807, 4635177.2214322, 4635190.76474251, 4635198.8907287, 
4635200.24505973), .Dim = c(19L, 2L))), list(structure(c(383240.252713044, 
383280.882643978, 383301.197609445, 383307.969264601, 383322.866905943, 
383343.18187141, 383374.331485126, 383386.520464407, 383408.189760905, 
383424.441733278, 383431.213388434, 383470.488988337, 383492.158284835, 
383521.95356752, 383543.622864018, 383554.457512267, 383576.126808766, 
383581.54413289, 4635198.8907287, 4635269.31594232, 4635288.27657675, 
4635307.23721119, 4635335.67816284, 4635360.0561214, 4635388.49707306, 
4635410.16636955, 4635433.18999708, 4635453.50496255, 4635472.46559699, 
4635504.96954173, 4635506.32387276, 4635499.55221761, 4635496.84355555, 
4635486.0089073, 4635476.52859008, 4635469.75693492), .Dim = c(18L, 
2L))))
like image 370
Tomas Avatar asked Dec 06 '22 06:12

Tomas


1 Answers

You can use some recycling here, It is faster:

max(rapply(mylist,t)[c(TRUE,FALSE)])
[1] 383581.5
max(rapply(mylist,t)[c(FALSE,TRUE)])
[1] 4635506

I use rapply(mylist,t) to unlist my list , since unlist(mylist) do it column by column.

EDIT to show how this works, I will use a short example:

ll <- list(list(matrix(1:4,ncol=2)),
+            list(matrix(4:1,ncol=2)))
> ll
[[1]]
[[1]][[1]]
     [,1] [,2]
[1,]    1    3
[2,]    2    4
[[2]]
[[2]][[1]]
     [,1] [,2]
[1,]    4    2
[2,]    3    1

Now if unlist my list

> unlist(ll)
[1] 1 2 3 4 4 3 2 1   ## col1 then col2
> rapply(ll,t)
[1] 1 3 2 4 4 2 3 1   ## row1 then row2

Now recycling

  rapply(ll,t)[c(TRUE,FALSE)] ## pickup 1,3,5,....elements
  [1] 1 2 4 3
  rapply(ll,t)[c(FALSE,TRUE)] ## pickup 2,4,6,....elements
  [1] 3 4 2 1
like image 183
agstudy Avatar answered Dec 22 '22 01:12

agstudy