Home > OS >  FALSE vs. F: Error mapply's SIMPLIFY argument: in SIMPLIFY=F
FALSE vs. F: Error mapply's SIMPLIFY argument: in SIMPLIFY=F

Time:05-26

This Question refers to this Is there a best way to append a list values to a sublist of a list in R?.

One of the solution is this:

a <- list(3,5,7)
l <- list(c(1,2,3), c(2,1,4), c(4,7,6))

mapply(c, l, a, SIMPLIFY=F)

If I try to apply it on my machine I get the error:

Error in SIMPLIFY == "array" : 
  comparison (1) is possible only for atomic and list types

If I use this -> there is no error:

mapply(c, l, a, SIMPLIFY = FALSE)

I want to understand why the error occurs in using SIMPLIFY =F and not in SIMPLIFY = FALSE.

I am using rstudio - cloud:

> version
               _                           
platform       x86_64-pc-linux-gnu         
arch           x86_64                      
os             linux-gnu                   
system         x86_64, linux-gnu           
status                                     
major          4                           
minor          1.3                         
year           2022                        
month          03                          
day            10                          
svn rev        81868                       
language       R                           
version.string R version 4.1.3 (2022-03-10)
nickname       One Push-Up  

CodePudding user response:

In a fresh R session, this error isn't reproducible:

a <- list(3,5,7)
l <- list(c(1,2,3), c(2,1,4), c(4,7,6))

mapply(c, l, a, SIMPLIFY=F)
#> [[1]]
#> [1] 1 2 3 3
#> 
#> [[2]]
#> [1] 2 1 4 5
#> 
#> [[3]]
#> [1] 4 7 6 7

However, we can replicate your error by overwriting F with a function:

F <- function() {}; mapply(c, l, a, SIMPLIFY=F)
#> Error in SIMPLIFY == "array" : 
#>   comparison (1) is possible only for atomic and list types

Which suggests that you have a function somewhere on your search path called F.

The reason that we can guess it is a function rather than, say, a data frame or a vector, is that we would only get this error if there is something being passed to SIMPLIFY that does not have a method defined for the == operator, and a function is the most likely candidate (especially since it is called F)

If you look at the source code for mapply, you will see that the SIMPLIFY argument gets passed to simplify2array if and only if it does not evaluate to an atomic FALSE:

function (FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE) 
{
    FUN <- match.fun(FUN)
    dots <- list(...)
    answer <- .Internal(mapply(FUN, dots, MoreArgs))
    if (USE.NAMES && length(dots)) {
        if (is.null(names1 <- names(dots[[1L]])) && is.character(dots[[1L]])) 
            names(answer) <- dots[[1L]]
        else if (!is.null(names1)) 
            names(answer) <- names1
    }
    if (!isFALSE(SIMPLIFY)) 
        simplify2array(answer, higher = (SIMPLIFY == "array"))
    else answer
}

If it is not an atomic FALSE, the SIMPLIFY argument is then tested for equality to the string "array" using the == operator. If the object cannot be tested for equality with a character string, we will get this error.

I think this question is a great example of why one should never use F as a variable name in R, and why one should always use FALSE instead of F.

  • Related