Using na.rm=T in pmin with do.call
Asked Answered
U

2

5

I want to extract the minimum value of each element of several matrix that are stored inside a list. I'm using pmin:

do.call(pmin, mylist)

The problem is that some elements of those matrix are NAs, and pmin yields a NA where I want it to yield the minimum value after excluding the NAs. I tried to solve my problem using do.call(pmin(na.rm=T), mylist)

but I get an error. I also tried with this answer: data.table and pmin with na.rm=TRUE argument, but I get the error because .SD is not on the environment. Simple code for a similar problem would be:

mymat1 <- matrix(rnorm(10), ncol=2)

mymat2 <- matrix(rnorm(10), ncol=2)
mymat2[2,2] <- NA

mymat3 <- matrix(rnorm(10), ncol=2)

mylist <- list(mymat1, mymat2, mymat3)

do.call(pmin, mylist)

I get a NA in the position [2,2] of the resulting matrix, and I want to get the minimum values ignoring NAs. Any suggestions? Thank you.

Unhallowed answered 6/6, 2018 at 22:10 Comment(0)
H
5

Concatenate the na.rm = TRUE as a named list element and then use pmin with do.call so that the parameter na.rm will be found

do.call(pmin, c(mylist, list(na.rm = TRUE)))
#          [,1]       [,2]
#[1,] -1.0830716 -0.1237099
#[2,] -0.5949517 -3.7873790
#[3,] -2.1003236 -1.2565663
#[4,] -0.4500171 -1.0588205
#[5,] -1.0937602 -1.0537657
Hoenack answered 6/6, 2018 at 22:14 Comment(2)
since mylist is already a list, there is no need of doing list(na.rm=TRUE) just c(mylist, na.rm = TRUE) will workBaum
That's exactly what I needed. Cheers.Unhallowed
M
3

if you use purrr / tidyverse you can use purrr::invoke.

library(purrr)
invoke(pmin,mylist,na.rm=TRUE)
#            [,1]       [,2]
# [1,] -0.3053884 -1.3770596
# [2,]  0.9189774 -0.4149946
# [3,] -0.1027877 -0.3942900
# [4,] -0.6212406 -1.4707524
# [5,] -2.2146999 -0.4781501

It is basically do.call with a ... argument and its source code is more or less @akrun's answer :

function (.f, .x = NULL, ..., .env = NULL) 
{
  .env <- .env %||% parent.frame()
  args <- c(as.list(.x), list(...))
  do.call(.f, args, envir = .env)
}

purrr::partial is also interesting :

pmin2 <- partial(pmin,na.rm=TRUE)
do.call(pmin2,mylist)
#            [,1]       [,2]
# [1,] -0.3053884 -1.3770596
# [2,]  0.9189774 -0.4149946
# [3,] -0.1027877 -0.3942900
# [4,] -0.6212406 -1.4707524
# [5,] -2.2146999 -0.4781501
Melanoma answered 6/6, 2018 at 23:2 Comment(1)
Great! Very simple. Thank you.Unhallowed

© 2022 - 2024 — McMap. All rights reserved.