Застрял на использовании мутации/суммирования dpylr для сопоставления цветов с переменными уровнями

Я никогда не мог найти хороший способ сделать это. Я пытаюсь создать пользовательскую функцию для сопоставления цветов RColorBrewer с уровнями переменных в data_frame. Я рисую цвета узлов в igraph, и для этого требуется цветовой вектор. Я сделал это так далеко, прежде чем получить ошибку.

library(tidyverse)
library(RColorBrewer)

 my_data <- data_frame(
    x = sample(c('red','white','foo'),25,T)
 ) 

my_data %>% 
  group_by(x) %>% 
  mutate(Blues = brewer.pal(n_distinct(x),'Spectral'))  ## this doesn't work

Мне нужна работающая функция. Что-то вроде следующего:

function(df,vary){
    df %>%
       group_by(vary) %>%
       mutate(Blues = brewer.pal(n_distinct(vary),'Spectral')) %>%
       select(Blues)
    }

Спасибо за любую помощь!


person elliot    schedule 10.11.2017    source источник
comment
Сколько цветов вы ожидаете от результата? Три цвета длины 25?   -  person Psidom    schedule 10.11.2017
comment
@Psidom, я бы хотел один столбец с тремя цветами. Тот, который соответствует/соответствует каждому уровню в x.   -  person elliot    schedule 10.11.2017


Ответы (1)


Вам не нужен group_by, просто используйте mutate и сгенерируйте нужные цвета с помощью brewer.pal(n_distinct(x), 'Spectral'), а затем сопоставьте цвета с переменными, используя match:

Примечание: я использовал синтаксис tidyeval для захвата переменной в стиле NSE, так как мы используем функцию с dplyr. Но вы можете запрограммировать иначе, если хотите.

var_to_color <- function(df, var) {
    var <- enquo(var)
    df %>% 
        mutate(Colors = brewer.pal(n_distinct(!!var), 'Spectral')[match(!!var, unique(!!var))]) %>%
        pull(Colors)
}

var_to_color(my_data, x)
# [1] "#FC8D59" "#FFFFBF" "#FFFFBF" "#FFFFBF" "#99D594" "#FFFFBF" "#99D594"
# [8] "#99D594" "#FC8D59" "#FFFFBF" "#FC8D59" "#FFFFBF" "#FFFFBF" "#99D594"
#[15] "#FC8D59" "#FC8D59" "#99D594" "#FFFFBF" "#FC8D59" "#FC8D59" "#FC8D59"
#[22] "#FC8D59" "#FFFFBF" "#FC8D59" "#FC8D59"

my_data$x
# [1] "white" "red"   "red"   "red"   "foo"   "red"   "foo"   "foo"   "white"
#[10] "red"   "white" "red"   "red"   "foo"   "white" "white" "foo"   "red"  
#[19] "white" "white" "white" "white" "red"   "white" "white"

Без использования dplyr функция, которая берет один вектор, а затем отображает его в цвета, вероятно, имеет больше смысла:

var_to_color <- function(var) brewer.pal(n_distinct(var), 'Spectral')[match(var, unique(var))]

var_to_color(my_data$x)
# [1] "#FC8D59" "#FFFFBF" "#FFFFBF" "#FFFFBF" "#99D594" "#FFFFBF" "#99D594"
# [8] "#99D594" "#FC8D59" "#FFFFBF" "#FC8D59" "#FFFFBF" "#FFFFBF" "#99D594"
#[15] "#FC8D59" "#FC8D59" "#99D594" "#FFFFBF" "#FC8D59" "#FC8D59" "#FC8D59"
#[22] "#FC8D59" "#FFFFBF" "#FC8D59" "#FC8D59"
person Psidom    schedule 10.11.2017
comment
Спасибо. Это прекрасно работает. Можете ли вы сказать мне, почему вы добавили '!!' делает? - person elliot; 10.11.2017
comment
Это часть синтаксиса tidyeval. Подробнее об этом можно прочитать здесь. В основном он оценивает символ в dplyr глаголах, таких как mutate и summarize, как столбец. - person Psidom; 10.11.2017