Как определить функцию, используемую geom_smooth()

Я хотел бы отобразить сюжет, созданный geom_smooth(), но для меня важно иметь возможность описать, как этот сюжет был создан.

Я вижу из документации, когда n >= 1000, gam используется в качестве функции сглаживания, но я не вижу, сколько узлов используется или какая функция генерирует сглаживание.

Пример:

library(ggplot2)

set.seed(12345)
n <- 3000
x1 <- seq(0, 4*pi,, n)
x2 <- runif(n)
x3 <- rnorm(n)
lp <- 2*sin(2* x1)+3*x2 + 3*x3
p <- 1/(1+exp(-lp))
y <- ifelse(p > 0.5, 1, 0)

df <- data.frame(x1, x2, x3, y)

# default plot
ggplot(df, aes(x = x1, y = y)) +
  geom_smooth() 

# specify method='gam'
# linear
ggplot(df, aes(x = x1, y = y)) +
  geom_smooth(method = 'gam') 

# specify gam and splines
# Shows non-linearity, but different from default
ggplot(df, aes(x = x1, y = y)) +
  geom_smooth(method = 'gam',
              method.args = list(family = "binomial"),
              formula = y ~ splines::ns(x, 7)) 

Если я хочу использовать параметры по умолчанию, есть ли способ определить функцию, используемую для создания сглаживания, чтобы я мог точно описать ее в разделе методов анализа?

вариации geom_smooth


person A Toll    schedule 28.11.2016    source источник
comment
возможный ответ здесь: stackoverflow.com /вопросы/9789871/   -  person Nate    schedule 29.11.2016
comment
Или, может быть, этот: stackoverflow.com/questions/15584541/, так как из документации ggplot2 следует, что он использует mgcv   -  person HFBrowning    schedule 29.11.2016
comment
Формула по умолчанию (согласно документации) для gam должна быть formula = y ~ s(x, bs = "cs"), поэтому k было установлено на любое значение по умолчанию из mgcv::s. Однако похоже, что в ggplot2_2.2.0 gam по умолчанию использует formula = y ~ x, поэтому подходит для прямой линии вместо любого вида сплайна. У меня есть сомнения, что это то, что он должен делать; результирующий сюжет теперь такой же, как и при использовании lm.   -  person aosmith    schedule 29.11.2016
comment
@aosmith Я на 2.2.0, но ggplot(diamonds, aes(price, carat)) + geom_smooth() определенно не прямой ..   -  person Axeman    schedule 29.11.2016
comment
@Axeman Но посмотрите, что произойдет, если вы вручную укажете method = "gam" вместо того, чтобы позволить ggplot выбрать игру из-за 1000 баллов. Кажется странным.   -  person aosmith    schedule 29.11.2016
comment
@aosmith Ха. Ты хочешь подать это, или я должен?   -  person Axeman    schedule 29.11.2016
comment
@Axeman Вы можете продолжать. Кто знает, может быть, так было всегда, и пользователь должен указать формулу, если решит использовать gam.   -  person aosmith    schedule 29.11.2016
comment
@aosmith, idk, я понизил версию до версии 1.0.0, и это уже было..   -  person Axeman    schedule 29.11.2016
comment
Для справки, Хэдли обратился к этому здесь: такое поведение (формула по умолчанию не меняется с от y ~ x до y ~ s(x, bs = "cs"), если method = "gam" указано явно) правильно; мы сообщаем формулу, но не изменяем ее автоматически. Это зависит от вас.   -  person Z.Lin    schedule 07.03.2019


Ответы (1)


Я написал функцию для обратного проектирования шагов, используемых в функции setup_params StatSmooth, чтобы получить фактические параметры метода/формулы, используемые для построения графика.

Функция ожидает объект ggplot в качестве входных данных с дополнительным необязательным параметром, указывающим слой, соответствующий geom_smooth (по умолчанию 1, если не указано). Он возвращает текстовую строку в виде "Method: [method used], Formula: [formula used]", а также выводит все параметры на консоль.

Предполагаемый вариант использования двоякий:

  1. Добавьте текстовую строку как есть к графику в качестве заголовка/подзаголовка/заголовка графика для быстрой справки во время анализа;
  2. Прочитайте распечатку консоли и включите информацию в другое место или отформатируйте ее вручную (например, проанализированные математические выражения) для аннотаций на графике, для отчета / презентации.

Функция:

get.params <- function(plot, layer = 1){

  # return empty string if the specified geom layer doesn't use stat = "smooth"
  if(!"StatSmooth" %in% class(plot$layers[[layer]]$stat)){
    message("No smoothing function was used in this geom layer.")
    return("")
  }

  # recreate data used by this layer, in the format expected by StatSmooth
  # (this code chunk takes heavy reference from ggplot2:::ggplot_build.ggplot)
  layer.data <- plot$layers[[layer]]$layer_data(plot$data)
  layout <- ggplot2:::create_layout(plot$facet, plot$coordinates)
  data <- layout$setup(list(layer.data), plot$data, plot$plot_env)
  data[[1]] <- plot$layers[[layer]]$compute_aesthetics(data[[1]], plot)
  scales <- plot$scales
  data[[1]] <- ggplot2:::scales_transform_df(scales = scales, df = data[[1]])
  layout$train_position(data, scales$get_scales("x"), scales$get_scales("y"))
  data <- layout$map_position(data)[[1]]

  # set up stat params (e.g. replace "auto" with actual method / formula)
  stat.params <- suppressMessages(
    plot$layers[[layer]]$stat$setup_params(data = data, 
                                           params = plot$layers[[layer]]$stat_params)
    )

  # reverse the last step in setup_params; we don't need the actual function
  # for mgcv::gam, just the name
  if(identical(stat.params$method, mgcv::gam)) stat.params$method <- "gam"

  print(stat.params)

  return(paste0("Method: ", stat.params$method, ", Formula: ", deparse(stat.params$formula)))
}

Демонстрация:

p <- ggplot(df, aes(x = x1, y = y)) # df is the sample dataset in the question

# default plot for 1000+ observations
# (method defaults to gam & formula to 'y ~ s(x, bs = "cs")')
p1 <- p + geom_smooth()
p1 + ggtitle(get.params(p1))

# specify method = 'gam'
# (formula defaults to `y ~ x`)
p2 <- p + geom_smooth(method='gam')
p2 + ggtitle(get.params(p2))

# specify method = 'gam' and splines for formula
p3 <- p + geom_smooth(method='gam',
              method.args = list(family = "binomial"),
              formula = y ~ splines::ns(x, 7))
p3 + ggtitle(get.params(p3))

# specify method = 'glm'
# (formula defaults to `y ~ x`)
p4 <- p + geom_smooth(method='glm')
p4 + ggtitle(get.params(p4))

# default plot for fewer observations
# (method defaults to loess & formula to `y ~ x`)
# observe that function is able to distinguish between plot data 
# & data actually used by the layer
p5 <- p + geom_smooth(data = . %>% slice(1:500))
p5 + ggtitle(get.params(p5))

сюжет

person Z.Lin    schedule 07.03.2019
comment
Как получить параметры уравнения? - person Aliton Oliveira; 24.05.2021