Как использовать NSE внутри fct_reorder() в ggplot2

Я хотел бы знать, как использовать выражение NSE (нестандартная оценка) в fct_reorder() в ggplot2 для репликации диаграмм для разных фреймов данных.

Это пример фрейма данных, который я использую для рисования диаграммы:

   travel_time_br30 travel_time_br30_int time_reduction shift not_shift total
1              0-30                    0             10  2780      3268  6048
2              0-30                    0             20  2779      3269  6048
3              0-30                    0             30  2984      3064  6048
4              0-30                    0             40  3211      2837  6048
5             30-60                   30             10  2139      2007  4146
6             30-60                   30             20  2159      1987  4146
7             30-60                   30             30  2363      1783  4146
8             30-60                   30             40  2478      1668  4146
9             60-90                   60             10   764       658  1422
10            60-90                   60             20   721       701  1422
11            60-90                   60             30   782       640  1422
12            60-90                   60             40   801       621  1422
13           90-120                   90             10   296       224   520
14           90-120                   90             20   302       218   520
15           90-120                   90             30   317       203   520
16           90-120                   90             40   314       206   520
17          120-150                  120             10    12        10    22
18          120-150                  120             20    10        12    22
19          120-150                  120             30    10        12    22
20          120-150                  120             40    13         9    22
21          150-180                  150             10    35        21    56
22          150-180                  150             20    40        16    56
23          150-180                  150             30    40        16    56
24          150-180                  150             40    35        21    56
      share
1  45.96561
2  45.94907
3  49.33862
4  53.09193
5  51.59190
6  52.07429
7  56.99469
8  59.76845
9  53.72714
10 50.70323
11 54.99297
12 56.32911
13 56.92308
14 58.07692
15 60.96154
16 60.38462
17 54.54545
18 45.45455
19 45.45455
20 59.09091
21 62.50000
22 71.42857
23 71.42857
24 62.50000

Это скрипты для рисования диаграммы из приведенного выше фрейма данных:

g.var <- "travel_time_br30"
go.var <- "travel_time_br30_int"

test %>% ggplot(.,aes_(x=as.name(x.var),y=as.name("share"),group=as.name(g.var))) +
    geom_line(size=1.4, aes(
                color=fct_reorder(travel_time_br30,order(travel_time_br30_int)))) 

введите здесь описание изображения

Поскольку у меня есть несколько фреймов данных с разными полями, такими как access_time_br30, access_time_br30_int вместо travel_time_br30 и travel_time_br30_int во фрейме данных, я установил две переменные (g.var и go.var), чтобы легко копировать несколько символов в одних и тех же скриптах.

Поскольку мне нужно переупорядочить группу факторов численно, в частности, изменив порядок travel_time_br30 на travel_time_br30_int, я использую функцию fct_reorder в ggplot2(., aes_(...)). Однако, если я использую aes_ с fct_reorder() в geom_line(), как показано в качестве примера в следующем сценарии, он возвращает сообщение об ошибке Error:fmust be a factor (or character vector).

geom_line(size=1.4, aes_(color=fct_reorder(as.name(g.var),order(as.name(go.var)))))

Fct_reorder(), похоже, не имеет версии NSE, такой как fct_reorder_(). Нельзя ли одновременно использовать aes_ и fct_reorder() в последовательности скриптов или есть какие-то другие решения?


person Hideo.S    schedule 04.05.2018    source источник
comment
подойдет ли вам выполнение fct_reorder до того, как мы вызовем ggplot()? предполагая, что он все еще находится внутри функции/цикла и NSE..   -  person Nate    schedule 04.05.2018
comment
Это работает со следующим скриптом: test %>% mutate(order=fct_reorder(travel_time_br30, travel_time_br30_int)) Однако это не работает, если я использую переменные с NSE ('mutate_') вместо того, чтобы указывать имя поля непосредственно в скрипте: mutate_(order=fct_reorder(as.name(g.var),as.name(go.var)))   -  person Hideo.S    schedule 04.05.2018


Ответы (1)


Основываясь на моем начальном опыте работы с tidy-eval, вы могли бы преобразовать свой факторный порядок в mutate() перед передачей данных в ggplot() и получить свой результат.

Извините, я не мог легко прочитать вашу таблицу выше из-за возврата строки, поэтому я сделал новый пример с mtcars, который, я думаю, отражает ваше намерение. (дайте мне знать, если это не так)

mtcars2 <- mutate(mtcars,
                  gear_int = 6 - gear,
                  gear_intrev = rev(gear_int)) %>%
    mutate_at(vars(cyl, gear), as.factor)


library(rlang)

gg_reorder <- function(data, col_var, col_order) {

    eq_var <- sym(col_var) # sym is flexible and my novice preference
    eq_ord <- sym(col_order)

    data %>% mutate(!!quo_name(eq_var) := fct_reorder(!!eq_var, !!eq_ord) ) %>%
        ggplot(aes_(~mpg, ~hp, color = eq_var)) +
          geom_line()

}

А теперь примените его к построению...

gg_reorder(mtcars2, "gear", "gear_int")

введите здесь описание изображения

gg_reorder(mtcars2, "gear", "gear_intrev")

введите здесь описание изображения

Я не указал все переменные aes_() в виде строк, но вы можете передать их как текст и использовать шаблон as.name(). Если вам нужно больше tidy-eval паттернов, Эдвин Тоэн написал кучу распространенных случаев.

person Nate    schedule 04.05.2018
comment
к вашему сведению, теперь вы можете использовать tidyeval с ggplot2 (версия для разработки). Вот пример - person Tung; 04.05.2018
comment
Уважаемый Нейт! Большое спасибо за ваше предложение! Хотя я столкнулся с множеством ошибок во время работы с трубой в dplyr, я смог добиться желаемого результата, основываясь на вашей идее. - person Hideo.S; 07.05.2018
comment
Уважаемый Tung: Это также очень помогло мне решить ошибки в операции. Большое спасибо!! - person Hideo.S; 07.05.2018