purrr 列表评估陌生度
purrr list evaluation strangeness
似乎列表是否有标题时 purrr 函数的计算结果不同,但为什么呢?这只是 "one of those things" 吗?
示例:
func_b <- function(x,y,z) paste(x,y,z)
## Works as expected
pmap(list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length), func_b) %>% head(2)
[[1]] [1] "5.1 3.5 1.4"
[[2]] [1] "4.9 3 1.4"
## Doesn't work
pmap(map(iris[,1:3],list),func_b)
Error in .f(Sepal.Length = .l[[c(1L, 1L)]], Sepal.Width = .l[[c(2L, 1L)]], : unused arguments (Sepal.Length = .l[[c(1, 1)]], Sepal.Width = .l[[c(2, 1)]], Petal.Length = .l[[c(3, 1)]])
但唯一的区别似乎是其中一个列表保留了标题,而另一个列表没有?
list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length) %>% map(head)
[[1]] [1] 5.1 4.9 4.7 4.6 5.0 5.4
[[2]] [1] 3.5 3.0 3.2 3.1 3.6 3.9
[[3]] [1] 1.4 1.4 1.3 1.5 1.4 1.7
as.list(iris[,1:3]) %>% map(head)
$Sepal.Length [1] 5.1 4.9 4.7 4.6 5.0 5.4
$Sepal.Width [1] 3.5 3.0 3.2 3.1 3.6 3.9
$Petal.Length [1] 1.4 1.4 1.3 1.5 1.4 1.7
class(list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length)) == class(as.list(iris[,1:3]))
[1] TRUE
str(list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length)); str(as.list(iris[,1:3]))
List of 3
$ : num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ : num [1:150] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ : num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
List of 3
$ Sepal.Length: num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num [1:150] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
如果我们只是去掉第二个列表的名字,它就没有问题。
aa <- as.list(iris[,1:3])
names(aa) <- NULL
pmap(aa,func_b) %>% head(2)
[[1]]
[1] "5.1 3.5 1.4"
[[2]]
[1] "4.9 3 1.4"
所以我的具体问题是:为什么标题会影响评估方法?有什么方法可以在不破坏 dplyr 管道以消除名称的情况下进行转换吗?
Axeman 是正确的,但您可以围绕它进行防御性和动态编程:
library(purrr)
func_b <- function(...) {
args <- list(...)
paste(args[[1]], args[[2]], args[[3]])
}
list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length) %>%
pmap(func_b) %>%
head(2)
## [[1]]
## [1] "5.1 3.5 1.4"
##
## [[2]]
## [1] "4.9 3 1.4"
iris[,1:3] %>% pmap(func_b) %>% head(3)
## [[1]]
## [1] "5.1 3.5 1.4"
##
## [[2]]
## [1] "4.9 3 1.4"
##
## [[3]]
## [1] "4.7 3.2 1.3"
func_c <- function(...) {
args <- list(...)
paste0(args, collapse = " ")
}
list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length) %>%
pmap(func_c) %>%
head(2)
## [[1]]
## [1] "5.1 3.5 1.4"
##
## [[2]]
## [1] "4.9 3 1.4"
iris[,1:3] %>% pmap(func_c) %>% head(3)
## [[1]]
## [1] "5.1 3.5 1.4"
##
## [[2]]
## [1] "4.9 3 1.4"
##
## [[3]]
## [1] "4.7 3.2 1.3"
iris[,1:2] %>% pmap(func_c) %>% head(3)
## [[1]]
## [1] "5.1 3.5"
##
## [[2]]
## [1] "4.9 3"
##
## [[3]]
## [1] "4.7 3.2"
似乎列表是否有标题时 purrr 函数的计算结果不同,但为什么呢?这只是 "one of those things" 吗?
示例:
func_b <- function(x,y,z) paste(x,y,z)
## Works as expected
pmap(list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length), func_b) %>% head(2)
[[1]] [1] "5.1 3.5 1.4"
[[2]] [1] "4.9 3 1.4"
## Doesn't work
pmap(map(iris[,1:3],list),func_b)
Error in .f(Sepal.Length = .l[[c(1L, 1L)]], Sepal.Width = .l[[c(2L, 1L)]], : unused arguments (Sepal.Length = .l[[c(1, 1)]], Sepal.Width = .l[[c(2, 1)]], Petal.Length = .l[[c(3, 1)]])
但唯一的区别似乎是其中一个列表保留了标题,而另一个列表没有?
list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length) %>% map(head)
[[1]] [1] 5.1 4.9 4.7 4.6 5.0 5.4
[[2]] [1] 3.5 3.0 3.2 3.1 3.6 3.9
[[3]] [1] 1.4 1.4 1.3 1.5 1.4 1.7
as.list(iris[,1:3]) %>% map(head)
$Sepal.Length [1] 5.1 4.9 4.7 4.6 5.0 5.4
$Sepal.Width [1] 3.5 3.0 3.2 3.1 3.6 3.9
$Petal.Length [1] 1.4 1.4 1.3 1.5 1.4 1.7
class(list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length)) == class(as.list(iris[,1:3]))
[1] TRUE
str(list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length)); str(as.list(iris[,1:3]))
List of 3
$ : num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ : num [1:150] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ : num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
List of 3
$ Sepal.Length: num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
$ Sepal.Width : num [1:150] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
$ Petal.Length: num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
如果我们只是去掉第二个列表的名字,它就没有问题。
aa <- as.list(iris[,1:3])
names(aa) <- NULL
pmap(aa,func_b) %>% head(2)
[[1]] [1] "5.1 3.5 1.4"
[[2]] [1] "4.9 3 1.4"
所以我的具体问题是:为什么标题会影响评估方法?有什么方法可以在不破坏 dplyr 管道以消除名称的情况下进行转换吗?
Axeman 是正确的,但您可以围绕它进行防御性和动态编程:
library(purrr)
func_b <- function(...) {
args <- list(...)
paste(args[[1]], args[[2]], args[[3]])
}
list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length) %>%
pmap(func_b) %>%
head(2)
## [[1]]
## [1] "5.1 3.5 1.4"
##
## [[2]]
## [1] "4.9 3 1.4"
iris[,1:3] %>% pmap(func_b) %>% head(3)
## [[1]]
## [1] "5.1 3.5 1.4"
##
## [[2]]
## [1] "4.9 3 1.4"
##
## [[3]]
## [1] "4.7 3.2 1.3"
func_c <- function(...) {
args <- list(...)
paste0(args, collapse = " ")
}
list(iris$Sepal.Length, iris$Sepal.Width, iris$Petal.Length) %>%
pmap(func_c) %>%
head(2)
## [[1]]
## [1] "5.1 3.5 1.4"
##
## [[2]]
## [1] "4.9 3 1.4"
iris[,1:3] %>% pmap(func_c) %>% head(3)
## [[1]]
## [1] "5.1 3.5 1.4"
##
## [[2]]
## [1] "4.9 3 1.4"
##
## [[3]]
## [1] "4.7 3.2 1.3"
iris[,1:2] %>% pmap(func_c) %>% head(3)
## [[1]]
## [1] "5.1 3.5"
##
## [[2]]
## [1] "4.9 3"
##
## [[3]]
## [1] "4.7 3.2"