使用来自 DF 列表的数据在多个图上使用 geom_segment 添加线
Adding lines using geom_segment on multiple plots with data from a list of DFs
我正在尝试向已保存的 ggplot 对象添加多行。线条的坐标存储在数据框列表中,每个单独的图都有一个数据框。我使用 lapply 成功创建了多个绘图,但是,调用 geom_segment 时代码失败。下面是示例数据和代码。
library(ggplot2)
library(tidyverse)
data(iris)
#Dataframes
m.slen <- iris[,c(1,5)]
m.swid <- iris[,c(2,5)]
m.plen <- iris[,c(3,5)]
m.pwid <- iris[,c(4,5)]
#List of dataframes
m.list = list(m.slen = m.slen,
m.swid = m.swid,
m.plen = m.plen,
m.pwid = m.pwid)
#Setting col names
m.list <- lapply(m.list, setNames, nm = c("data", "species"))
#Creating list of data frames with coordinates for geom_segment
meanV = lapply(m.list, function(x) mean(x$data, na.rm = TRUE))
coordy1 = lapply(m.list, function(x) x %>%
group_by(species) %>%
summarise(max = max(data, na.rm=TRUE)) %>%
pull(max) + 2)
#Table with dynamic values
line.plot <- list()
for(i in 1:4) {
line.plot[[i]] <-
tibble(x1 = meanV[[i]],
x2 = meanV[[i]]+1,
y1 = coordy1[[i]][1],
y2 = coordy1[[i]][1])
}
#Creating first set of plots, using first list of DFs
plots <- lapply(m.list,function(x)
p <- ggplot(x, aes( x= data, fill = species)) +
geom_histogram(stat = "count") +
ggtitle(names(m.list)))
print(plots)
#Adding segments using second list of DFs
final_plots <- lapply(plots,function(x)
plots + geom_segment(data = line.plot,
aes(x = x1, y = y1, xend = x2, yend = y2)))
一切正常,直到最后一步,我收到以下错误
Error in fortify()
: ! data
must be a data frame, or other
object coercible by fortify()
, not a list
欢迎任何意见或建议。谢谢
问题是 line.plot
是一个列表。为了达到您想要的结果,您可以使用 purrr::map2
遍历您的地块列表和段的数据帧列表:
注意:我还添加了 inherit.aes = FALSE
到 geom_segment
,否则你也会得到一个错误。
final_plots <- purrr::map2(plots, line.plot, function(x, y) {
x + geom_segment(
data = y,
aes(x = x1, y = y1, xend = x2, yend = y2), inherit.aes = FALSE
)
})
final_plots[[1]]
EDIT 使用 base R 你可以用 mapply
:
获得相同的结果
final_plots <- mapply(function(x, y) {
x + geom_segment(
data = y,
aes(x = x1, y = y1, xend = x2, yend = y2), inherit.aes = FALSE
)
}, x = plots, y = line.plot, SIMPLIFY = FALSE)
或者感谢@Parfait 使用 Map
:
的评论
final_plots <- Map(function(x, y) {
x + geom_segment(
data = y,
aes(x = x1, y = y1, xend = x2, yend = y2), inherit.aes = FALSE
)
}, x = plots, y = line.plot)
我正在尝试向已保存的 ggplot 对象添加多行。线条的坐标存储在数据框列表中,每个单独的图都有一个数据框。我使用 lapply 成功创建了多个绘图,但是,调用 geom_segment 时代码失败。下面是示例数据和代码。
library(ggplot2)
library(tidyverse)
data(iris)
#Dataframes
m.slen <- iris[,c(1,5)]
m.swid <- iris[,c(2,5)]
m.plen <- iris[,c(3,5)]
m.pwid <- iris[,c(4,5)]
#List of dataframes
m.list = list(m.slen = m.slen,
m.swid = m.swid,
m.plen = m.plen,
m.pwid = m.pwid)
#Setting col names
m.list <- lapply(m.list, setNames, nm = c("data", "species"))
#Creating list of data frames with coordinates for geom_segment
meanV = lapply(m.list, function(x) mean(x$data, na.rm = TRUE))
coordy1 = lapply(m.list, function(x) x %>%
group_by(species) %>%
summarise(max = max(data, na.rm=TRUE)) %>%
pull(max) + 2)
#Table with dynamic values
line.plot <- list()
for(i in 1:4) {
line.plot[[i]] <-
tibble(x1 = meanV[[i]],
x2 = meanV[[i]]+1,
y1 = coordy1[[i]][1],
y2 = coordy1[[i]][1])
}
#Creating first set of plots, using first list of DFs
plots <- lapply(m.list,function(x)
p <- ggplot(x, aes( x= data, fill = species)) +
geom_histogram(stat = "count") +
ggtitle(names(m.list)))
print(plots)
#Adding segments using second list of DFs
final_plots <- lapply(plots,function(x)
plots + geom_segment(data = line.plot,
aes(x = x1, y = y1, xend = x2, yend = y2)))
一切正常,直到最后一步,我收到以下错误
Error in
fortify()
: !data
must be a data frame, or other object coercible byfortify()
, not a list
欢迎任何意见或建议。谢谢
问题是 line.plot
是一个列表。为了达到您想要的结果,您可以使用 purrr::map2
遍历您的地块列表和段的数据帧列表:
注意:我还添加了 inherit.aes = FALSE
到 geom_segment
,否则你也会得到一个错误。
final_plots <- purrr::map2(plots, line.plot, function(x, y) {
x + geom_segment(
data = y,
aes(x = x1, y = y1, xend = x2, yend = y2), inherit.aes = FALSE
)
})
final_plots[[1]]
EDIT 使用 base R 你可以用 mapply
:
final_plots <- mapply(function(x, y) {
x + geom_segment(
data = y,
aes(x = x1, y = y1, xend = x2, yend = y2), inherit.aes = FALSE
)
}, x = plots, y = line.plot, SIMPLIFY = FALSE)
或者感谢@Parfait 使用 Map
:
final_plots <- Map(function(x, y) {
x + geom_segment(
data = y,
aes(x = x1, y = y1, xend = x2, yend = y2), inherit.aes = FALSE
)
}, x = plots, y = line.plot)