asachet
asachet

Reputation: 6921

purrr::map_int: Can't coerce element 1 from a double to a integer

I am having the weirdest bug with map_int from the purrr package.

# Works as expected
purrr::map_int(1:10, function(x) x)
#>  [1]  1  2  3  4  5  6  7  8  9 10

# Why on earth is that not working?
purrr::map_int(1:10, function(x) 2*x)
#> Error: Can't coerce element 1 from a double to a integer

# or that?
purrr::map_int(1:10, round)
#> Error: Can't coerce element 1 from a double to a integer

Created on 2019-03-28 by the reprex package (v0.2.1)

I run 3.5.2 in rocker container (Debian) with the latest github version of everything:

sessioninfo::package_info("purrr")
#>  package  * version    date       lib source                             
#>  magrittr   1.5.0.9000 2019-03-28 [1] Github (tidyverse/magrittr@4104d6b)
#>  purrr      0.3.2.9000 2019-03-28 [1] Github (tidyverse/purrr@25d84f7)   
#>  rlang      0.3.2.9000 2019-03-28 [1] Github (r-lib/rlang@9376215)       
#> 
#> [1] /usr/local/lib/R/site-library
#> [2] /usr/local/lib/R/library

Upvotes: 2

Views: 3299

Answers (2)

IceCreamToucan
IceCreamToucan

Reputation: 28695

The documentation from help(map) says

The output of .f will be automatically typed upwards , e.g. logical -> integer -> double -> character

It appears to be following the larger ordering given in help(c). For example, this produces an error map_dbl(1:10, ~complex(real = .x, imaginary = 1)).

NULL < raw < logical < integer < double < complex < character < list < expression

As you can see in that ordering, double-to-integer is a downward conversion. So, the function is designed to not do this kind of conversion.

The solution is to either write a function .f which outputs integer (or lower) classed objects (as in @Stéphane Laurent's answer), or just use as.integer(map(.x, .f)).

This is a kind of type-checking, which can be a useful feature for preventing programming mistakes.

Upvotes: 4

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84599

2*x is not an integer because 2 is not. Do instead

purrr::map_int(1:10, function(x) 2L*x)

Upvotes: 5

Related Questions