Как добавить несколько трасс на один сюжет? - PullRequest
3 голосов
/ 19 февраля 2020

Я хотел бы добавить трассировки оси Y к графическому объекту, используя карту из пакета purrr. Но вместо добавления новых трасс к существующему графику, он создает отдельные графики для каждого графика. См .:

library(purrr)
library(plotly)

data("iris")

p = plot_ly(iris, type = "bar")
xaxis = ~Species
map(c(~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width), ~add_trace(p, x = xaxis, y = .x))

Есть ли способ исправить это?

1 Ответ

3 голосов
/ 19 февраля 2020

map является неправильной функцией для этого, потому что она итеративно применяет одну и ту же функцию к различным аргументам по очереди, по определению.

То, что вы хотите сделать, отличается: вы хотите агрегировать результат по разным аргументам путем применения данной операции к текущему агрегату и следующему аргументу. В терминологии функционального программирования это известно как сокращение , и purrr предоставляет для него функцию reduce.

trace_vars = c(~Sepal.Length, ~Sepal.Width, ~Petal.Length, ~Petal.Width)
result = reduce(trace_vars, ~ add_trace(.x, x = xaxis, y = .y), .init = p)

Это фактически то же самое, что и

add_trace(
  add_trace(
    …,
    x = xaxis, y = ~Sepal.Width
  ),
  x = xaxis, y = ~Sepal.Length
)

Вы можете инвертировать направление с помощью аргумента reduce .dir.

Чтобы включить имена, используйте reduce2 с адаптированной формулой. К сожалению, извлечение имен из формул немного раздражает:

trace_names = map_chr(trace_vars, ~ as.character(.x[[2L]]))

result = reduce2(
    trace_vars, trace_names,
    ~ add_trace(..1, x = xaxis, y = ..2, name = ..3),
    .init = p
)
...