您需要将与group 变量和构面变量对应的列添加到数据框int2 和int3 中,以便回归线仅出现在相应的面板上,并按组进行适当的拆分。
您的示例中似乎部分完成了此操作,但由于 ID 列被赋予了不同的名称,因此不正确。它们应该与dd 中的变量同名。
int2 = co$`childid:schoolid`
int2$childid <- substr(rownames(int2), 1, 9)
int2$schoolid <- substr(rownames(int2), 11, 14)
int3 = co$schoolid
int3$schoolid <- rownames(int3)
ggplot(data = dd, aes(x = year, y = math, group = factor(childid)))+ geom_point()+ facet_wrap(~schoolid)+
geom_abline(data = int2, aes(intercept=`(Intercept)`, slope=year)) +
geom_abline(data = int3, aes(intercept=`(Intercept)`, slope=year), color=2)
到目前为止一切顺利。但看起来在您的示例图中,回归线的 x 值范围与数据相同。要解决此问题,您需要将 geom_abline 替换为 geom_segment。我计算了每个schoolid 和childid 所需的x 值范围,并以这种方式找到了段的端点。
# Calculate range of values for schoolid and childid.
year_range_by_schoolid <- dd %>% group_by(schoolid) %>% summarize(min_year = min(year), max_year = max(year))
year_range_by_childid <- dd %>% group_by(schoolid, childid) %>% summarize(min_year = min(year), max_year = max(year))
# Find min and max points for each line.
int2 <- int2 %>%
mutate(schoolid = as.integer(schoolid),
childid = as.integer(childid)) %>%
left_join(year_range_by_childid) %>%
mutate(min_y = `(Intercept)` + year * min_year,
max_y = `(Intercept)` + year * max_year)
int3 <- int3 %>%
mutate(schoolid = as.integer(schoolid)) %>%
left_join(year_range_by_schoolid) %>%
mutate(min_y = `(Intercept)` + year * min_year,
max_y = `(Intercept)` + year * max_year)
ggplot(data = dd, aes(x = year, y = math, group = factor(childid)))+ geom_point()+ facet_wrap(~schoolid)+
geom_segment(data = int2, aes(x = min_year, y = min_y, xend = max_year, yend = max_y)) +
geom_segment(data = int3, aes(x = min_year, y = min_y, xend = max_year, yend = max_y, group = factor(schoolid)), color=2)