如何合并vcd包绘制的马赛克图并保留标签?
问题:合并
vcd::mosaic生成的马赛克图报错 我尝试合并一系列通过vcd::mosaic生成的马赛克图,由于无法使用par(mfrow())将图形排布为2×2布局,于是在生成马赛克图并通过labeling_cells添加频率标签后,使用grid.grab()处理,但合并图形时出现错误。
原代码
mos<- function(bcoh, sex1, name, union2,m){ data2<-dataset_full_paper2_101 %>% dplyr::filter(birthc==bcoh & sex=-sex1 & union==union2) genga<-xtabs (~edu34+edu34_pa, data=data2) t2<-round(prop.table(genga),2) t3<-data.frame(t2) t3$edu34<-as.numeric(t3$edu34) t3$edu34_pa<- as.numeric(t3$edu34_pa) genga2<-structable(~edu34+edu34_pa, data=t3) dimnames (genga2)<-list (edu34=c(1,2,3),edu34_pa=c(1,2,3)) txt<-as.table(matrix(paste0(t2), 3,3)) dimnames (txt)=dimnames (genga2) colors=c("#d1e8e2", "#d1e8e2","#d1e8e2","#a9d6ca", "#a9d6ca", "#a9d6ca","#7cc7c0", "#7cc7c0", "#7cc7c0") mosaic(x=genga2, pop-F, direction='v', gp-gpar (fill=colors), colorize=T, shade=T, labeling_args=list(set_varnames=c(edu34="Education", edu34_pa="Partner's education")),set_labels=c(list(edu34=c("Low", "Interm","High"), edu34_pa=c("Low", "Interm", "High"))) labeling_cells(text=txt, margin=0,clip=T)(genga2) m=grid.grab() } mos (0,2, "Married women born in 1932-1950",2,m1) mos (1,2, "Married women born in 1951-1970",2,m2) grid. arrange(m1,m2)
错误信息
mos (0,2, "Married women born in 1932-1950",2,m1) 警告信息: 1: In grabDL (warn, wrap, wrap.grobs, ...) : viewport被覆盖(抓取结果可能不准确) 2: In grabDL (warn, wrap, wrap.grobs, ...) : viewport被覆盖(抓取结果可能不准确) mos (1,2, "Married women born in 1951-1970",2,m2) 警告信息: 1: In grabDL (warn, wrap, wrap.grobs, ...) : viewport被覆盖(抓取结果可能不准确) 2: In grabDL (warn, wrap, wrap.grobs, ...) : viewport被覆盖(抓取结果可能不准确) grid. arrange(m1,m2) Error in gList(...) : only 'grobs' allowed in "gList"
解决方案
1. 修复核心语法错误
原代码存在多处语法错误,直接导致逻辑失效:
sex=-sex1改为sex==sex1(R中判断相等需用双等号)pop-F改为pop=FALSE,gp-gpar (fill=colors)改为gp=gpar(fill=colors)(赋值需用单等号)- 移除无用的
name参数,调整函数参数逻辑
2. 修正函数返回逻辑
原函数试图修改外部变量m1、m2,但R函数默认传值,不会直接修改外部对象。改为让函数返回grid.grab()的结果,再赋值给m1、m2
3. 解决viewport警告
给grid.grab()添加wrap=TRUE参数,将抓取的图形封装在独立viewport中,避免覆盖问题
修正后的完整代码
library(vcd) library(dplyr) library(grid) library(gridExtra) mos <- function(bcoh, sex1, union2){ data2 <- dataset_full_paper2_101 %>% dplyr::filter(birthc == bcoh & sex == sex1 & union == union2) genga <- xtabs(~edu34 + edu34_pa, data = data2) t2 <- round(prop.table(genga), 2) t3 <- data.frame(t2) t3$edu34 <- as.numeric(t3$edu34) t3$edu34_pa <- as.numeric(t3$edu34_pa) genga2 <- structable(~edu34 + edu34_pa, data = t3) dimnames(genga2) <- list(edu34 = c(1,2,3), edu34_pa = c(1,2,3)) txt <- as.table(matrix(paste0(t2), 3,3)) dimnames(txt) <- dimnames(genga2) colors <- c("#d1e8e2", "#d1e8e2","#d1e8e2","#a9d6ca", "#a9d6ca", "#a9d6ca","#7cc7c0", "#7cc7c0", "#7cc7c0") # 生成马赛克图并配置标签 mosaic(x = genga2, pop = FALSE, direction = 'v', gp = gpar(fill = colors), colorize = TRUE, shade = TRUE, labeling_args = list(set_varnames = c(edu34 = "Education", edu34_pa = "Partner's education")), set_labels = list(edu34 = c("Low", "Interm","High"), edu34_pa = c("Low", "Interm", "High"))) # 添加频率标签 labeling_cells(text = txt, margin = 0, clip = TRUE)(genga2) # 抓取并返回grob对象,解决viewport警告 return(grid.grab(wrap = TRUE)) } # 调用函数获取grob对象 m1 <- mos(0, 2, 2) m2 <- mos(1, 2, 2) # 2列布局合并图形 grid.arrange(m1, m2, ncol = 2)
错误原因解析
Error in gList(...):原函数未正确返回grob对象,m1、m2实际为NULL,不是合法的图形对象,导致grid.arrange报错viewport被覆盖警告:未给grid.grab()添加wrap=TRUE,抓取的图形共享viewport导致冲突,添加参数后可封装为独立图形单元
内容的提问来源于stack exchange,提问作者Lydia Palumbo
相关产品推荐
相关产品推荐

