R语言for循环中从不同数据框获取ggplot标题显示NA的解决求助
解决ggplot2绘图时ggtitle无法正确显示对应explanation文本的问题
你正在使用R语言的ggplot2绘制批量图表,代码能按marker_id拆分数据绘图,但图表标题始终显示NA,无法调用marker_data数据框中explanation列的对应文本。
当前代码:
markers <- unique(patient_flow$marker_id) marker_data <- ap_fcm_raw$markerdata library(ggplot2) for (i in markers){ p <- ggplot(data = subset(patient_flow, marker_id == i))+ aes(x = as.numeric(pbd_cat), y = result, color = study)+ ggtitle(marker_data$explanation[i])+ geom_smooth()+ geom_point()+ labs(x = "Post Burn day") ggsave(p, file=paste0("FCM_plots/plot_", i, ".png")) }
marker_data的数据结构:
structure(list(marker_id = c("events_001", "ptot_002", "events_003", "ppar_004", "ptot_005", "events_006"), name = c("all_e", "all_e_t", "cell_e", "cell_p", "cell_t", "single_e"), cell_type = c("events", "events", "cells", "cells", "cells", "singlets"), gate = c("All Events\r\nEvents\r\n\r\n", "All Events\r\n%\r\nTotal\r\n\r\n", "Cells\r\nEvents\r\n\r\n", "Cells\r\n%\r\nParent\r\n\r\n", "Cells\r\n%\r\nTotal\r\n\r\n", "Singlets\r\nEvents\r\n\r\n"), explanation = c("All events in total", "Percentage of all total events", "Number of cells", "Percentage of Cells of Parent gate", "Percentage of cells of Total events", "Number of single events" ), panel = c("p2", "p2", "p2", "p2", "p2", "p2")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))
问题原因
问题出在索引匹配上:i是patient_flow$marker_id的字符型取值(比如"events_001"),但marker_data的行索引是默认的数字序列(1、2、3...),直接用marker_data$explanation[i]会尝试用字符值作为位置索引,导致无法匹配到对应的explanation文本,返回NA。
解决方案
方案1:将marker_data的行名设置为marker_id
修改marker_data的行名,让行名与marker_id一致,这样就能直接用i索引对应的explanation:
markers <- unique(patient_flow$marker_id) marker_data <- ap_fcm_raw$markerdata # 设置行名为marker_id rownames(marker_data) <- marker_data$marker_id library(ggplot2) for (i in markers){ p <- ggplot(data = subset(patient_flow, marker_id == i))+ aes(x = as.numeric(pbd_cat), y = result, color = study)+ # 现在可以直接通过i索引到对应的explanation ggtitle(marker_data$explanation[i])+ geom_smooth()+ geom_point()+ labs(x = "Post Burn day") ggsave(p, file=paste0("FCM_plots/plot_", i, ".png")) }
方案2:用match函数获取对应位置索引
在循环中用match()找到当前i在marker_data$marker_id中的位置,再提取explanation:
markers <- unique(patient_flow$marker_id) marker_data <- ap_fcm_raw$markerdata library(ggplot2) for (i in markers){ # 找到当前marker_id对应的行位置 idx <- match(i, marker_data$marker_id) p <- ggplot(data = subset(patient_flow, marker_id == i))+ aes(x = as.numeric(pbd_cat), y = result, color = study)+ ggtitle(marker_data$explanation[idx])+ geom_smooth()+ geom_point()+ labs(x = "Post Burn day") ggsave(p, file=paste0("FCM_plots/plot_", i, ".png")) }
方案3:提前合并数据框(推荐)
将patient_flow和marker_data按marker_id合并,这样可以避免循环中的索引操作,代码更简洁且不易出错:
library(ggplot2) library(dplyr) # 合并两个数据框 combined_data <- patient_flow %>% left_join(marker_data, by = "marker_id") # 按marker_id分组绘图 combined_data %>% group_by(marker_id) %>% group_walk(function(.data, .key){ p <- ggplot(.data)+ aes(x = as.numeric(pbd_cat), y = result, color = study)+ ggtitle(.data$explanation[1])+ # 每组的explanation是相同的,取第一个即可 geom_smooth()+ geom_point()+ labs(x = "Post Burn day") ggsave(p, file=paste0("FCM_plots/plot_", .key$marker_id, ".png")) })
内容的提问来源于stack exchange,提问作者Marcel Vlig
相关产品推荐
相关产品推荐

