NMDS分析中使用gg_ordisurf/ordisurf时,如何在平滑曲面计算中忽略NA值?
解决gg_ordisurf处理含NA连续变量的方案
要实现保留所有NMDS样点,同时仅用无NA的连续变量值计算平滑曲面,可以通过手动分离拟合数据、单独生成曲面图层再组合的方式实现,具体步骤如下:
核心思路
gg_ordisurf底层依赖vegan的ordisurf函数,而ordisurf默认无法处理含NA的环境变量。我们可以:
- 从数据中筛选出无NA的样点,仅用这些数据拟合平滑曲面
- 先绘制包含所有样点的NMDS基础图
- 将拟合好的曲面图层叠加到基础图上
完整代码示例
library(vegan) library(ggordiplots) library(ggplot2) # 示例数据 community_matrix <- matrix(rpois(50, lambda = 5), nrow = 10) rownames(community_matrix) <- paste0("Site", 1:10) colnames(community_matrix) <- paste0("Sp", 1:5) NMDS = metaMDS(community_matrix, k=2, trace = 0, distance = "bray") coords= as.data.frame(scores(NMDS, "sites")) # 所有样点的NMDS坐标 coords$continuous <- c(3, 5, NA, 2, 4, NA, 6, 7, 5, 3) # 含NA的连续变量 # 1. 筛选出无NA的拟合数据(仅用于计算曲面) fit_data <- na.omit(coords) # 2. 用vegan::ordisurf拟合平滑曲面,不直接绘图 surf_fit <- ordisurf( x = scores(NMDS, "sites")[rownames(fit_data), ], # 对应无NA样点的NMDS坐标 y = fit_data$continuous, # 无NA的连续变量 plot = FALSE # 仅返回拟合结果,不生成基础图 ) # 3. 绘制包含所有样点的NMDS基础图 base_plot <- gg_ordiplot(NMDS, display = "sites", plot = FALSE) + geom_point(data = coords, aes(x = NMDS1, y = NMDS2), size = 3) + # 保留所有样点 labs(x = "NMDS1", y = "NMDS2") # 4. 叠加平滑曲面等高线和标签 final_plot <- base_plot + geom_contour(data = surf_fit$grid, aes(x = x, y = y, z = z), colour = "darkred") + geom_text(data = surf_fit$labels, aes(x = x, y = y, label = label), colour = "darkred", size = 4) print(final_plot)
效果说明
- 所有样点(包括连续变量为NA的)都会显示在NMDS图中
- 平滑曲面仅基于有有效连续变量值的样点计算,完全忽略NA值,无需删除样点或插补数据
内容的提问来源于stack exchange,提问作者Maxime Buron
相关产品推荐
相关产品推荐

