Coolsun
Coolsun

Reputation: 189

Find the maximum values of a variable in a list

I have a list of the following structure & I intend to find the maximum value of X2 in the second variable (b) in the list

sample data

[[1]]

[[1]]$a

[1] 2

[[1]]$b

   X1  X2
1  58 1686729

2 106 1682303


[[2]]

[[2]]$a

[1] 3

[[2]]$b

   X1  X2

1  24 1642468

2  89 1695581

3 156 1634019

I looked into multiple filters that can be applied to the list like:

library(rlist)
list.filter(result, max(b$area))

and also tried lapply but with no success

lapply(result, function(x) x[which.max(x$b)])

I need the following output:

a      x1    x2
2      58   1686729
3      89   1695581   

Upvotes: 1

Views: 1151

Answers (2)

Tonio Liebrand
Tonio Liebrand

Reputation: 17719

You can also use sapply():

t(sapply(list, function(elem){
  c(a = elem$a, elem$b[which.max(elem$b$area), ])
}))

Upvotes: 1

RLave
RLave

Reputation: 8374

With lapply() you can find the max of X2 in $b in each list, then cbind() with the a element.

l_max <- lapply(l, function(x) {
  b <- x$b
  cbind(a=x$a, b[which.max(b$X2),])
})

Use bind_rows() from dplyr for binding together.

l_max %>% 
  dplyr::bind_rows()
#     a X1      X2
# 1   2 58 1686729
# 2   3 89 1695581

Example data:

l <- list(
  list(a = 2, 
       b = data.frame(X1 = c(58, 106),  X2 = c(1686729, 1682303))),
  list(a = 3, 
       b = data.frame(X1 = c(24, 89,156),  X2 = c(1642468, 1695581,1634019)))
)

With your example:

l_max <- lapply(l, function(x) {
  b <- x$b
  cbind(a = x$a, b[which.max(b[,2]),]) # NOTICE I used [,2] to refer to the second column
                             #b$area works too if all df share the col name
})

l_max %>% 
  dplyr::bind_rows()
#   a  rt    area
# 1 2  58 1686729
# 2 3  89 1695581
# 3 4 101 1679889
# 4 5  88 1695983
# 5 6 105 1706445
# 6 7 121 1702019

Another solution with purrr::map_df() avoids the use of bind_rows():

purrr::map_df(l, function(x) {
  b <- x$b
  cbind(a = x$a, b[which.max(b[,2]),]) 
})

All base R using mapply():

t(mapply(function(x) {
  b <- x$b
  cbind(a = x$a, b[which.max(b[,2]),]) 
}, l))

Or with Map():

do.call("rbind", Map(function(x) {
  b <- x$b
  cbind(a = x$a, b[which.max(b[,2]),]) 
}, l))

Upvotes: 1

Related Questions