在R中绘制术后结局随时间变化的测量值图表(含缺失值处理)
Let's break this down into two practical approaches: ggplot2 (tidyverse-style, great for flexibility and customization) and base R (no extra packages required). First, we'll fix the data format—your wide dataset needs reshaping to long format for smoother plotting, and we'll explicitly handle missing values along the way.
1. ggplot2 Approach
First, we'll reshape your wide data to long format (critical for grouping patient trajectories) and set a logical order for time points so the x-axis makes clinical sense.
Step 1: Load Packages and Reshape Data
# Load core tidyverse packages (ggplot2 + tidyr) library(tidyverse) # Your original dataset dat <- data.frame(Preop=c(-2,0.5,-0.25,1.5), PO_1M=c(-1.5,0.2,-0.1,1.0), PO_6M=c(-1.2,0.1,-0.05,0.5), PO_1Y=c(-1.0,0.05,0,0.25)) # Add a patient ID column to track individual trajectories dat$Patient <- 1:nrow(dat) # Reshape to long format, and set ordered time point labels dat_long <- dat %>% pivot_longer(cols = -Patient, names_to = "Time", values_to = "Value") %>% mutate(Time = factor(Time, levels = c("Preop", "PO_1M", "PO_6M", "PO_1Y"), labels = c("术前", "术后1个月", "术后6个月", "术后1年"))) # Optional: Drop rows with missing values (ggplot will skip them automatically if you skip this step) dat_long_clean <- dat_long %>% drop_na(Value)
Step 2: Create the Plot
This plot shows individual patient trends, highlights the y=0 convergence point, and handles missing data intuitively (lines break where follow-up data is missing).
ggplot(dat_long, aes(x = Time, y = Value, group = Patient, color = Patient)) + # Draw lines for each patient's trajectory geom_line(na.rm = TRUE, alpha = 0.7) + # Add points for each time point measurement geom_point(na.rm = TRUE, size = 2) + # Add a dashed horizontal line at y=0 to show convergence target geom_hline(yintercept = 0, color = "black", linetype = "dashed") + # Customize labels and theme for readability labs(x = "时间点", y = "测量值", title = "术后结局随时间变化趋势") + theme_minimal() + # Optional: Hide legend if you have a large number of patients theme(legend.position = "none")
2. Base R Approach
If you prefer avoiding external packages, here's a base R solution that achieves the same goal. We'll use matplot and manual loops to draw patient trajectories.
Step 1: Prepare Data
# Your original dataset dat <- data.frame(Preop=c(-2,0.5,-0.25,1.5), PO_1M=c(-1.5,0.2,-0.1,1.0), PO_6M=c(-1.2,0.1,-0.05,0.5), PO_1Y=c(-1.0,0.05,0,0.25)) # Define custom time point labels and their positions on the x-axis time_labels <- c("术前", "术后1个月", "术后6个月", "术后1年") time_pos <- 1:length(time_labels)
Step 2: Create the Plot
# Set up the empty plot area with custom axes limits plot(NULL, xlim = range(time_pos), ylim = range(dat, na.rm = TRUE), xlab = "时间点", ylab = "测量值", main = "术后结局随时间变化趋势", xaxt = "n") # Add the custom x-axis labels axis(1, at = time_pos, labels = time_labels) # Add a dashed horizontal line at y=0 abline(h = 0, lty = 2, col = "black") # Loop through each patient to draw their line and points for (i in 1:nrow(dat)) { lines(time_pos, dat[i,], col = i, lwd = 1, na.rm = TRUE) points(time_pos, dat[i,], col = i, pch = 16, na.rm = TRUE) } # Optional: Add a legend (skip if you have hundreds of patients) legend("topright", legend = paste("患者", 1:nrow(dat)), col = 1:nrow(dat), lty = 1, bty = "n")
Notes on Missing Values
Both approaches automatically handle missing values using na.rm = TRUE. In ggplot2, lines will break at missing data points; in base R, lines() will skip gaps where data is missing, which clearly indicates missing follow-up without distorting trends.
内容的提问来源于stack exchange,提问作者Elizabeth Driskill

