purrr map_int() in R: Return an Integer Vector
purrr map_int() applies a function to each element of a list or vector and returns an integer vector. It is the type-stable counterpart of map() for whole-number results, such as counts and lengths.
map_int(x, length) # element count per list item map_int(df, ~ sum(is.na(.x))) # NA count per column map_int(df, ~ length(unique(.x))) # distinct values per column map_int(words, nchar) # character count per string map_int(x, \(v) v * 2L) # anonymous function, integer result map_int(x, length, .progress = TRUE) # show a progress bar
Need explanation? Read on for examples and pitfalls.
What map_int() does in one sentence
map_int() is a type-stable iterator. It loops over every element of .x, calls .f on each one, and binds the results into a plain integer vector the same length as the input. If any result cannot become an integer, the call fails loudly instead of returning a surprising type.
That strictness is the point. Base R's sapply() guesses the output type and can hand you a list when you expected a vector. map_int() removes the guess: the answer is always an integer vector, or it is an error you can see immediately.
map_int() guarantees an integer vector, code downstream can rely on that type without defensive checks. The error you get on a bad result is cheaper than a silent type bug found in production.Syntax
map_int() takes an input and a function. The two required arguments are .x, the list or vector to iterate over, and .f, the function applied to each element.
You can write .f three ways: a named function (length), a purrr formula (~ sum(is.na(.x))) where .x is the current element, or a native lambda (\(v) length(v)). All three are equivalent; pick whichever reads best.
Worked examples
Counting is the canonical job for map_int(). Each example below returns one whole number per element, so the integer output type fits naturally.
Count missing values in every column of a data frame. A data frame is a list of columns, so map_int() iterates column by column.
Count how many distinct values each column holds. This is a fast cardinality check before modelling.
Apply a named function directly. Here nchar returns the character count of each string.
Use a lambda when the result needs explicit integer literals. The L suffix marks 2L as an integer so the output type is exact.
map_int() vs map() and the other variants
Every map variant differs only in its return type. The loop is identical; the suffix picks the output. Choose the variant that matches the type each call to .f produces.
| Function | Returns | Use when .f produces |
|---|---|---|
map() |
list | anything, including mixed types |
map_int() |
integer vector | whole numbers (counts, lengths) |
map_dbl() |
double vector | decimals (means, ratios) |
map_chr() |
character vector | strings |
map_lgl() |
logical vector | TRUE or FALSE |
The decision rule is simple. If .f returns a count or a length, use map_int(). If it returns an average, a proportion, or any fractional number, use map_dbl(). When in doubt, use map() and inspect the list first.
map_int(x, f) is vapply(x, f, integer(1)). Both promise an integer vector, but map_int() supports formula and lambda shorthand and gives clearer error messages.Common pitfalls
Most map_int() errors trace back to one rule: each result must coerce to a single integer. These three mistakes break that rule.
A function that returns a fractional double cannot become an integer. Averaging columns produces decimals, so map_int() rejects them.
The fix is to use map_dbl() whenever .f can return a decimal.
A function that returns more than one value per element also fails, because map_int() expects exactly length 1.
Aggregate first so each call yields one number, for example ~ diff(range(.x)).
map_int(c("1", "2"), identity) errors even though the strings look numeric. Wrap the result yourself: map_int(c("1", "2"), as.integer).Try it yourself
Try it: Use map_int() on the mtcars data frame to count how many distinct values appear in each column. Save the result to ex_distinct.
Click to reveal solution
Explanation: map_int() iterates over each column of mtcars. The formula ~ length(unique(.x)) returns one whole number per column, so the integer return type fits and the result is a named integer vector.
Related purrr functions
map_int() is one of a family. Reach for these when the return type changes:
map()returns a list for any result type.map_dbl()returns a double vector for decimal results.map_chr()returns a character vector for string results.map_lgl()returns a logical vector for TRUE or FALSE results.map2_int()iterates two inputs in parallel and returns an integer vector.
FAQ
What is the difference between map_int() and map() in R?
map() always returns a list, regardless of what .f produces. map_int() returns a plain integer vector and checks every result. Use map() when results vary in type or length, and map_int() when each result is a single whole number. The integer return type makes map_int() output ready for arithmetic, indexing, or comparison without any unlisting step.
Why does map_int() give a coercion error?
The error appears when .f returns something that cannot become an integer, most often a fractional double like a mean, or a value longer than one. map_int() enforces an integer-vector contract, so it stops instead of silently changing type. Switch to map_dbl() for decimal results, or aggregate the result down to a single whole number per element.
Can map_int() return NA values?
Yes. If .f returns NA_integer_ for an element, map_int() keeps it as a missing value in the integer output. A bare logical NA also coerces cleanly. What it will not accept is NULL or a zero-length result, since those cannot fill an integer slot and trigger a length error instead.
Is map_int() faster than sapply()?
Performance is roughly equal; both loop in C-backed code. The real gain from map_int() is reliability. sapply() may return a list, a vector, or a matrix depending on the data, while map_int() always returns an integer vector or errors. That predictability prevents type bugs that surface far from their cause.