【问题标题】:Save intermediate list output in dplyr pipeline and map it back to another list further down the pipeline - R将中间列表输出保存在 dplyr 管道中,并将其映射回管道下方的另一个列表 - R
【发布时间】:2019-09-24 06:17:44
【问题描述】:

我正在使用dplyr 管道对数据集中的组运行 pcas。我从group_split 开始,所以我正在处理一个列表。为了运行prcomp() 函数,只能包含每个列表的numeric 列,但我希望将factor 列带回最后进行绘图。我尝试在管道的中途使用{. ->> temp} 保存中间输出,但由于它是一个列表,我不知道如何在绘图时索引分组列。

library(tidyverse)
library(ggbiplot)

iris %>%
  group_split(Species, keep = T) %>% #group by species, one pca per species
  {. ->> temp} %>%  # save intermediate output to preserve species column for use in plotting later
  map(~.x %>% select_if(is.numeric) %>% select_if(~var(.) != 0) %>% 
        prcomp(scale. = TRUE))%>% #run pca on numeric columns only
  map(~ggbiplot(.x), label=temp$Species)#plot each pca, labeling points as species names form the temporary object

这可以为iris数据集中的每个物种生成一个pca图,但由于temp$species = NULL,这些点没有被标记。

【问题讨论】:

  • 能否先保存temp <- unique(iris$Species)而不将其保存为中间输出,然后在map(~ggbiplot(.x), label=temp)中使用? ggbiplot 也不适用于 R 3.6.1 吗?

标签: r dplyr pca ggbiplot


【解决方案1】:

如果您使用map2() 并将.y 参数作为物种列表传递,您可以获得我认为您想要的结果。请注意,在您的原始代码中,labels 参数位于 ggbiplot() 函数之外并被忽略。

library(tidyverse)
library(ggbiplot)

iris %>%
  group_split(Species, keep = T) %>% 
  {. ->> temp} %>%  
  map(~.x %>% 
        select_if(is.numeric) %>%
        select_if(~var(.) != 0) %>% 
        prcomp(scale. = TRUE)) %>% 
  map2(map(temp, "Species"), ~ggbiplot(.x, labels = .y))

针对您的评论,如果您想添加第三个参数,您可以使用pmap() 而不是map2()。在下面的示例中,pmap() 被传递给ggbiplot() 参数的(嵌套)数据列表。请注意,我已更改 new 变量,使其成为一个因素,而不是跨组的常量。

iris %>%
  mutate(new = factor(sample(1:3, 150, replace = TRUE))) %>%
  group_split(Species, keep = T) %>% 
  {. ->> temp} %>%  
  map(~.x %>% 
        select_if(is.numeric) %>%
        select_if(~var(.) != 0) %>% 
        prcomp(scale. = TRUE)) %>% 
  list(map(temp, "Species"), map(temp, "new")) %>%
  pmap(~ ggbiplot(pcobj = ..1, labels = ..2, groups = ..3))

【讨论】:

  • 感谢您的回答。我知道如何在ggbiplot 调用中引入.z 元素吗?类似~ggbiplot(.x, labels = .y, groups=.z),如果数据有另一个分组列?例如。 iris$new<-c(rep('a',50),rep('b',50),rep('c',50))
  • @J.Con - 对于map() 系列,要使用具有两个以上参数的函数,您可以将符号更改为..1..2..3 等。
  • 谢谢。对不起,我就是想不通?
  • 非常感谢!!
【解决方案2】:

一种选择是使用splitimap

library(tidyverse)
library(ggbiplot)
iris %>%
split(.$Species) %>%  # save intermediate output to preserve species column for use in plotting later
map(~.x %>% select_if(is.numeric) %>% select_if(~var(.) != 0) %>% 
        prcomp(scale. = TRUE)) %>% 
imap(~ggbiplot(.x, labels = .y))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-30
    • 2021-05-30
    • 2017-05-29
    • 1970-01-01
    • 2021-12-18
    • 2022-10-14
    • 1970-01-01
    • 2021-06-14
    相关资源
    最近更新 更多