我想更好地理解R中的函数式编程。 我想使用 purrr
,但我将使用 rapply
来演示我想要理解的内容。 首先,以下是一个简单的例子:
您可以使用 map
获取 mtcars
数据集每列的平均值:
library(tidyverse)
mtcars %>% map_dbl(mean)
mpg cyl disp hp drat wt qsec
20.090625 6.187500 230.721875 146.687500 3.596563 3.217250 17.848750
vs am gear carb
0.437500 0.406250 3.687500 2.812500
我该如何使用purrr
将mean
映射到按cyl
分割的mtcars
数据集上?
library(tidyverse)
mtcars_split <- mtcars %>% split(.$cyl)
mtcars_split %>% map(mean)
$`4`
[1] NA
$`6`
[1] NA
$`8`
[1] NA
Warning messages:
1: In mean.default(.x[[i]], ...) :
argument is not numeric or logical: returning NA
2: In mean.default(.x[[i]], ...) :
argument is not numeric or logical: returning NA
3: In mean.default(.x[[i]], ...) :
argument is not numeric or logical: returning NA
我理解为什么这不起作用:split
会创建一个列表,现在我正在尝试将mean
map
到该新列表的每个元素上,这些元素是data.frame
。 这次map
ping的尝试相当于(如果需要,请更正我):
mean(mtcars_split[1])
mean(mtcars_split[2])
mean(mtcars_split[3])
显然这样是不起作用的 - 你不能仅仅对一个 data.frame
取 mean
。我真正想要的是做到这一点的东西:
mtcars_split[[1]] %>% map(mean)
mtcars_split[[2]] %>% map(mean)
mtcars_split[[3]] %>% map(mean)
问题是,我只是无法理解如何在purrr
中实现这一点。在寻找解决此问题(看起来非常基础)的方法时,我发现了rapply
,它似乎可以实现我想要的功能,但是不属于 purrr
的范畴(而且输出的格式也不完全符合我的要求,但那不重要):
rapply(mtcars_split, mean, how = "unlist")
4.mpg 4.cyl 4.disp 4.hp 4.drat 4.wt
26.6636364 4.0000000 105.1363636 82.6363636 4.0709091 2.2857273
4.qsec 4.vs 4.am 4.gear 4.carb 6.mpg
19.1372727 0.9090909 0.7272727 4.0909091 1.5454545 19.7428571
6.cyl 6.disp 6.hp 6.drat 6.wt 6.qsec
6.0000000 183.3142857 122.2857143 3.5857143 3.1171429 17.9771429
6.vs 6.am 6.gear 6.carb 8.mpg 8.cyl
0.5714286 0.4285714 3.8571429 3.4285714 15.1000000 8.0000000
8.disp 8.hp 8.drat 8.wt 8.qsec 8.vs
353.1000000 209.2142857 3.2292857 3.9992143 16.7721429 0.0000000
8.am 8.gear 8.carb
0.1428571 3.2857143 3.5000000
rapply
递归运用显然是我的答案关键-我认为我需要嵌套的map
——一个用于提取mtcars_split
中三个data.frame
的每一列,然后另一个用于对每个提取的列运行mean
。然而,我还没有能够使它起作用。
我认为Jenny Bryan在她的purrr
教程中已经解决了这个问题,她使用了一个map()
在一个map()
内,但我无法理解她在做什么。她指出这个例子可能在教程早期没有充分解释,我已经在这里要求她详细说明,但还没有得到答复(我知道她很忙!)。
group_by
。 - F. Privémtcars %>% split(.$cyl) %>% map(map, mean)
- missusemtcars %>% group_by(cyl) %>% summarise_all(mean)
。然而,有时候你需要迭代遍历嵌套列表的第二层级别,这时你可以使用modify_depth
。将map
放在map
内部是可能的,但如果你使用缩写的~
/.x
样式的匿名函数,可能会让人感到困惑。 - alistaire