Отличный вопрос, Тьебо, спасибо за публикацию.
Как вы уже поняли, проблема в том, что значения NA
удаляются из ваших данных, прежде чем они передаются в compute_group
. Расширяющая виньетка ggplot не упоминает об этом, но ваши данные сначала передаются через функцию-член compute_layer
вашего объекта ggproto. Поскольку вы не определили метод compute_layer
, ваш класс StatIcen
наследует метод от класса ggplot2::Stat
.
Если вы посмотрите на исходный код этого метода в ggplot2::Stat$compute_layer
, вы увидите, что именно здесь ваши значения NA
удаляются, используя функцию remove_missing
, которая удаляет строки в вашем фрейме данных. с отсутствующими значениями в любом из названных столбцов. Предположительно, вы по-прежнему хотите, чтобы значения NA
были удалены, если они появляются в столбце time
, но не в том случае, если они появляются в time2
.
Так что все, что я сделал здесь, это скопировал исходный код из Stat$compute_layer
и немного скорректируйте вызов remove_missing
, затем сделайте его членом StatIcen
:
StatIcen <- ggplot2::ggproto("StatIcen", Stat,
required_aes = c("time", "time2"),
compute_group = function(data, scales){
fit_icens <- survival::survfit.formula(
survival::Surv(time = data$time, time2 = data$time2,
type = "interval2") ~ 1, data = data)
data.frame(x = fit_icens$time, y = fit_icens$surv)
},
compute_layer = function (self, data, params, layout)
{
ggplot2:::check_required_aesthetics(self$required_aes, c(names(data),
names(params)), snake_class(self))
data <- remove_missing(data, params$na.rm, "time",
ggplot2:::snake_class(self), finite = TRUE)
params <- params[intersect(names(params), self$parameters())]
args <- c(list(data = quote(data), scales = quote(scales)), params)
ggplot2:::dapply(data, "PANEL", function(data) {
scales <- layout$get_scales(data$PANEL[1])
tryCatch(do.call(self$compute_panel, args),
error = function(e) {
warning("Computation failed in `",
ggplot2:::snake_class(self),
"()`:\n", e$message, call. = FALSE)
ggplot2:::new_data_frame()
})
})
}
)
Итак, мы получаем:
ggplot(testdf, aes(time = time, time2 = time2)) + stat_icen()