【发布时间】:2020-11-26 23:48:21
【问题描述】:
我终于尝试从 for 循环跳到 purrr。基本示例非常直观,但翻译 for 循环一直很棘手,尤其是在尝试将输出对象分配给列表时。 考虑以下示例,我尝试将嵌套 for 循环的输出分配给命名列表元素。
library(tidyverse)
# output list
loop_list <- list()
# iterate over colors
for (color in diamonds %>% distinct(color) %>% pull()){
# sublist for each color
loop_list[[color]] <- list()
# iterate over cuts
for(cut in diamonds %>% distinct(cut) %>% pull()){
# filter data
data <- diamonds %>%
filter(color == color & cut == cut)
# define output
out <- data %>%
pull(price) %>%
mean()
# assign output to sublist of its color
loop_list[[color]][[cut]] <- out
# clean up filtered data set
rm(data)
}
}
此嵌套循环将输出对象分配给数据集每种颜色的正确命名的子列表。我的 purrr 尝试创建了类似的东西,但没有命名的子列表。所有输出对象都分配到同一个列表中,这不是我想要的。
grid <- expand_grid(color = diamonds %>% distinct(color) %>% pull(),
cut = diamonds %>% distinct(cut) %>% pull())
myfunc <- function(data, color, cut){
# create output object
out <- data %>%
# filter data
filter(color == color & cut == cut) %>%
pull(price) %>%
mean()
# return output
return(out)
}
purrr_list <- grid %>%
pmap(myfunc, data = diamonds)
有没有办法用 purrr 达到相同的输出?我知道使用<<- 进行全局分配是可能的,但据我了解,这通常是不鼓励的。
【问题讨论】:
-
这对于本质上只是一个制表/聚合练习来说似乎很复杂 - 例如:
out <- tapply(diamonds$price, diamonds[c("color","cut")], FUN=mean)然后你可以像out["D", "Fair"]那样对单个值进行子集化,out["D", ]对单个颜色或 @ 987654327@ 单次切割。 -
我选择聚合是因为它是一个易于复制的示例。如果它是 ggplot-objects 你的解决方案不再起作用了。感谢您的回答,但我正在尝试了解 purrr 家族的工作原理。