У меня есть data.frame
, который выглядит как:
type id x y label from to polarity group
1 link 3 560 -219 <NA> 2 1 + 1
8 var 2 426 -276 hours worked per week NA NA <NA> 1
7 var 1 610 -226 accomplishments per week NA NA <NA> 1
и функция link_coordinates
, которая вычисляет координаты from_x/from_y
и to_x/to_y
для всех элементов типа link
путем поиска координат связанных элементов типа var
. Ссылки обозначены from
и to
:
link_coordinates <- function(cld) {
cld$from_x <- NA; cld$from_y <- NA; cld$to_x <- NA; cld$to_y <- NA
for(i in 1:nrow(cld)) {
if(cld$type[i] == "link") {
cld$from_x[i] <- cld$x[cld$id == cld$from[i]]
cld$from_y[i] <- cld$y[cld$id == cld$from[i]]
cld$to_x[i] <- cld$x[cld$id == cld$to[i]]
cld$to_y[i] <- cld$y[cld$id == cld$to[i]]
}
}
return(cld)
}
Я могу предварительно рассчитать эти координаты и затем построить ссылку:
library(ggplot2)
cld_linked <- link_coordinates(cld)
ggplot(as.data.frame(cld_linked)) + geom_curve(aes(x = from_x, y = from_y, xend = to_x, yend = to_y))
Теперь я хочу сделать этот предварительный расчет (вместе с другими вещами) внутри пользовательского Geom
, называемого GeomLink
. При этом вместо сюжета я получаю ошибку:
ggplot(as.data.frame(cld)) + geom_link()
Error in FUN(X[[i]], ...) : object 'from_x' not found
Почему и как изменить свои функции GeomLink
и geom_link
, чтобы они создавали график сверху?
Вот мой data.frame
:
cld <- structure(list(type = c("link", "var", "var"), id = c(3, 2, 1
), x = c(560, 426, 610), y = c(-219, -276, -226), label = c(NA,
"hours worked per week", "accomplishments per week"), from = c(2,
NA, NA), to = c(1L, NA, NA), polarity = c("+", NA, NA), group = c(1L,
1L, 1L)), .Names = c("type", "id", "x", "y", "label", "from",
"to", "polarity", "group"), row.names = c(1L, 8L, 7L), class = "data.frame")
и вот мои GeomLink
и geom_link
функции:
GeomLink <- ggplot2::ggproto("GeomLink", ggplot2::GeomCurve,
required_aes = c("id", "x", "y", "from", "to", "polarity", "type", "group"),
default_aes = ggplot2::aes(id = id, x = x, y = y, xend = x, yend = y, from = from, to = to, polarity = polarity, type = type, group = group, colour = "black",
size = 4, angle = 0, hjust = 0.5, vjust = 0.5,
alpha = NA, fontface = 1,
lineheight = 1.2, length = 10),
setup_data = function(data, params){
data <- link_coordinates(data)
data <- data[data$type == "link", ]
print(data)
})
geom_link <- function(mapping = ggplot2::aes(x = from_x, y = from_y, xend = to_x, yend = to_y, id = id, from = from, to = to, polarity = polarity, type = type), data = NULL, position = "identity", stat = "identity",
..., curvature = 0.2, angle = 90, ncp = 5, arrow = NULL,
arrow.fill = NULL, lineend = "butt", na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE)
{
ggplot2::layer(data = data, mapping = mapping, stat = stat, geom = GeomLink,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(arrow = arrow, arrow.fill = arrow.fill,
curvature = curvature, angle = angle, ncp = ncp,
lineend = lineend, na.rm = na.rm, ...))
}