Сохраните вывод промежуточного списка в конвейере dplyr и отобразите его в другом списке далее по конвейеру - R - PullRequest
2 голосов
/ 24 сентября 2019

Я запускаю pcas для групп в наборе данных, используя dplyr конвейеры.Я начинаю с 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

Это работает для получения одного участка pca для каждого вида в наборе данных iris, но, начиная с temp$species = NULL, точки не помечаются.

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019

Если вы используете 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))

enter image description here

В ответ на вашкомментарий, если вы хотите добавить третий аргумент, вы можете использовать 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))

enter image description here

1 голос
/ 24 сентября 2019

Один из вариантов - использовать split и imap

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))
...