lapply 대신 purrr :: map을 사용하는 이유는 무엇입니까?
내가 사용해야하는 이유가 있습니까?
map(<list-like-object>, function(x) <do stuff>)
대신에
lapply(<list-like-object>, function(x) <do stuff>)
출력은 동일해야하며 내가 만든 벤치 마크 lapply
는 약간 더 빠름 을 보여줍니다 ( map
모든 비표준 평가 입력을 평가해야합니다).
왜 그런 간단한 경우에 실제로 전환해야하는지에 대한 이유가 purrr::map
있습니까? 나는 하나의 좋아하는 또는 구문에 대한 싫어하는 여기에 대해 요구 하진 않았어, 다른 기능은 purrr 등으로 제공하지만, 엄격하게 비교 약 purrr::map
으로 lapply
즉, 표준 평가를 사용하여 가정 map(<list-like-object>, function(x) <do stuff>)
. purrr::map
성능, 예외 처리 등의 측면에서 이점이 있습니까? 아래의 의견은 그렇지 않다고 제안하지만 누군가가 조금 더 자세히 설명 할 수 있습니까?
purrr에서 사용하는 유일한 기능이 map()
아니오 인 경우에는 이점이 크지 않습니다. Rich Pauloo가 지적했듯이 주요 장점은 map()
일반적인 특수한 경우에 대한 간단한 코드를 작성할 수있는 헬퍼입니다.
~ . + 1
에 해당function(x) x + 1
list("x", 1)
와 같습니다function(x) x[["x"]][[1]]
. 이 도우미는 좀 더 일반적 입니다. 자세한 내용[[
은 참조?pluck
하십시오. 들어 데이터 rectangling 의.default
인수는 특히 유용합니다.
그러나 대부분 단일 *apply()
/ map()
기능을 사용하지 않고 많은 기능을 사용하고 있으며 purrr의 장점은 기능 간의 일관성이 훨씬 뛰어납니다. 예를 들면 다음과 같습니다.
첫 번째 주장
lapply()
은 데이터이다. 첫 번째 인수mapply()
는 함수입니다. 모든 맵 함수에 대한 첫 번째 인수는 항상 데이터입니다.로
vapply()
,sapply()
그리고mapply()
당신은 출력에 억제 이름을 선택할 수 있습니다USE.NAMES = FALSE
; 그러나lapply()
그 주장은 없습니다.매퍼 함수에 일관된 인수를 전달하는 일관된 방법은 없습니다. 대부분의 기능을 사용할 수
...
있지만mapply()
사용MoreArgs
(당신이 기대를 호출 할MORE.ARGS
), 그리고Map()
,Filter()
그리고Reduce()
새로운 익명 함수를 만들 것으로 기대합니다. 맵 함수에서 상수 인수는 항상 함수 이름 뒤에옵니다.거의 모든 purrr 함수는 유형이 안정적입니다. 함수 이름에서만 출력 유형을 예측할 수 있습니다.
sapply()
또는에 대해서는 사실이 아닙니다mapply()
. 그렇습니다vapply()
. 하지만에 해당하는 것은 없습니다mapply()
.
당신은 이러한 작은 차이가 중요하지 않다고 생각할 수도 있습니다 (일부 사람들은 기본 R 정규 표현식보다 더 엄격한 이점이 없다고 생각하지만) 내 경험상 프로그래밍 할 때 불필요한 마찰을 일으 킵니다 (서로 다른 인수 순서는 항상 여행에 사용되었습니다) 큰 아이디어뿐만 아니라 많은 부수적 인 세부 사항도 배워야하기 때문에 함수형 프로그래밍 기술을 배우기가 더 어려워집니다.
Purrr은 또한 기본 R에없는 몇 가지 편리한 맵 변형을 채 웁니다.
modify()
[[<-
"제자리에서"수정 하는 데 사용하는 데이터 유형을 유지합니다 ._if
변형 과 함께 이것은 (IMO beautiful) 코드를 허용합니다.modify_if(df, is.factor, as.character)
map2()
x
와에 동시에 매핑 할 수 있습니다y
. 이를 통해 다음과 같은 아이디어를보다 쉽게 표현할 수 있습니다.map2(models, datasets, predict)
imap()
를 통해 동시에x
그 색인 (이름 또는 위치) 을 매핑 할 수 있습니다 . 이를csv
통해 디렉토리에있는 모든 파일을 쉽게로드 할 수 있으며filename
각 파일에 열을 추가 할 수 있습니다.dir("\\.csv$") %>% set_names() %>% map(read.csv) %>% imap(~ transform(.x, filename = .y))
walk()
입력을 보이지 않게 리턴합니다. 부작용에 대한 함수를 호출 할 때 유용합니다 (예 : 디스크에 파일 쓰기).
같은 다른 도우미를 언급하지 않는 safely()
및 partial()
.
개인적으로 purrr을 사용할 때 마찰이 적고 쉽게 기능 코드를 작성할 수 있습니다. 아이디어를 생각하고 구현하는 것 사이의 간격을 줄입니다. 그러나 마일리지는 다를 수 있습니다. 실제로 도움이되지 않는 한 purrr을 사용할 필요가 없습니다.
마이크로 벤치 마크
예, map()
보다 약간 느립니다 lapply()
. 그러나 사용하는 비용은 map()
나 lapply()
에 의해 구동 무엇있는 거 매핑, 루프를 수행하지 오버 헤드. 아래의 마이크로 벤치 마크는 map()
비교 비용이 lapply()
요소 당 약 40 ns이며 대부분의 R 코드에 실질적으로 영향을 미치지 않는 것으로 보입니다.
library(purrr)
n <- 1e4
x <- 1:n
f <- function(x) NULL
mb <- microbenchmark::microbenchmark(
lapply = lapply(x, f),
map = map(x, f)
)
summary(mb, unit = "ns")$median / n
#> [1] 490.343 546.880
편리함 과 속도 를 비교 purrr
하고 lapply
정리합니다 .
1. purrr::map
lapply보다 문법적으로 더 편리합니다
extract second element of the list
map(list, 2)
which as @F. Privé pointed out, is the same as:
map(list, function(x) x[[2]])
with lapply
lapply(list, 2) # doesn't work
we need to pass an anonymous function...
lapply(list, function(x) x[[2]]) # now it works
...or as @RichScriven pointed out, we pass [[
as an argument into lapply
lapply(list, `[[`, 2) # a bit more simple syntantically
So if find yourself applying functions to many lists using lapply
, and tire of either defining a custom function or writing an anonymous function, convenience is one reason to move to favor purrr
.
2. Type-specific map functions simply many lines of code
map_chr()
map_lgl()
map_int()
map_dbl()
map_df()
- my favorite, returns a data frame.
Each of these type-specific map functions returns an atomic list (vector), rather than the lists returned by map()
and lapply()
. If you're dealing with nested lists of atomic vectors within, you can use these type-specific map functions to pull out the vectors directly, and coerce vectors directly into int, dbl, chr vectors. The base R version would look something like as.numeric(sapply(...))
, as.character(sapply(...))
, etc. This gives purrr
another point for convenience and functionality.
3. Convenience aside, lapply
is [slightly] faster than map
Using purrr
's convenience functions, as @F. Privé pointed out slows down processing a bit. Let's race each of the 4 cases I presented above.
# devtools::install_github("jennybc/repurrrsive")
library(repurrrsive)
library(purrr)
library(microbenchmark)
library(ggplot2)
mbm <- microbenchmark(
lapply = lapply(got_chars[1:4], function(x) x[[2]]),
lapply_2 = lapply(got_chars[1:4], `[[`, 2),
map_shortcut = map(got_chars[1:4], 2),
map = map(got_chars[1:4], function(x) x[[2]]),
times = 100
)
autoplot(mbm)
And the winner is....
lapply(list, `[[`, 2)
In sum, if raw speed is what you're after: base::lapply
(although it's not that much faster)
For simple syntax and expressibility: purrr::map
This excellent purrr
tutorial highlights the convenience of not having to explicitly write out anonymous functions when using purrr
, and the benefits of type-specific map
functions.
If we do not consider aspects of taste (otherwise this question should be closed) or syntax consistency, style etc, the answer is no, there’s no special reason to use map
instead of lapply
or other variants of the apply family, such as the stricter vapply
.
PS: To those people gratuitously downvoting, just remember the OP wrote:
I am not asking here about one's likes or dislikes about the syntax, other functionalities provided by purrr etc., but strictly about comparison of purrr::map with lapply assuming using the standard evaluation
If you do not consider syntax nor other functionalities of purrr
, there's no special reason to use map
. I use purrr
myself and I'm fine with Hadley's answer, but it ironically goes over the very things the OP stated upfront he was not asking.
참고URL : https://stackoverflow.com/questions/45101045/why-use-purrrmap-instead-of-lapply
'Programing' 카테고리의 다른 글
Linq는 IN (A, B, C)에있는 목록에서 객체를 선택합니다 (0) | 2020.06.17 |
---|---|
골랑에서 정수 범위를 반복하는 방법이 있습니까? (0) | 2020.06.17 |
전체 파일을 문자열 변수로 읽는 방법 (0) | 2020.06.17 |
방금 발생한 MySQL 경고를 어떻게 표시합니까? (0) | 2020.06.17 |
다른 비동기 메서드 대신 이벤트를 기다리는 것이 가능합니까? (0) | 2020.06.17 |