谁能给我解释一下,为什么使用purrr.Purrr.会出错,但使用lapply同样的调用似乎可以。
map(list(list(a=1, b=2, c=3), list(a=1, b=2, c=3)), `[[<-`, "b", 1)
但同样的调用lapply似乎也可以。
我的印象是 [[<-
只是一个函数调用,所以希望purrr和lapply在这里做同样的事情。
问题在于 purrr::as_mapper()
,其中 map()
引擎盖下的电话。考虑一下两者的区别。
x <- list( a=1, b=2, c=3 )
`[[<-`( x, "b", 1 ) # This is what lapply() calls
# x is unchanged, returns modified list
purrr::as_mapper(`[[<-`)( x, "b", 1 ) # This is what map() calls
# x is modified in-place, returns value 1
第二个函数调用就像你输入了下面的赋值表达式一样:
(x[["b"]] <- 1)
# [1] 1
当函数被传给下面的函数时,一定会引起问题 map()
的内部结构。有趣的是,用一个 ~
lambda 工作,但返回 "错误 "的结果。
y <- list(list(a=1, b=2, c=3), list(a=1, b=2, c=3))
purrr::map( y, ~purrr::as_mapper(`[[<-`)(.x, "b", 1) )
# [[1]]
# [1] 1
# [[2]]
# [1] 1
purrr::map( y, purrr::as_mapper(`[[<-`), "b", 1 )
# Error in list(a = 1, b = 2, c = 3)[["b"]] <- 1 :
# target of assignment expands to non-language object
正确的 purrr
相当于你的 lapply()
的例子会是这样的。
r1 <- lapply(y, `[[<-`, "b", 1)
r2 <- purrr::map(y, purrr::modify_at, "b", ~1)
r3 <- purrr::map(y, ~`[[<-`(.x, "b", 1))
identical( r1, r2 ) # TRUE
identical( r1, r3 ) # TRUE
在上面的例子中: modify_at()
返回修改后的列表,就像 [[<-(...)
的,而tilde ~
是需要的,因为 modify_at()
期待一个函数。另一种方法是将 `[[<-`
变成 ~
兰姆达: