You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

geom_smooth在部分facet_wrap中无法连接含NA的geom_point问题

问题:geom_smooth()无法在所有分面中连接数据点

你有一个包含study、celltype、value、time.numeric的data.frame,尝试用geom_smooth()连接所有geom_point(),但发现该函数仅在部分分面生效,同时收到以下警告:

Warning messages:
1: Removed 46 rows containing non-finite values (stat_smooth).
2: In simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  ... :
  span too small.   fewer data values than degrees of freedom.
3: In simpleLoess(y, x, w, span, degree = degree, parametric = parametric,  ... :
  pseudoinverse used at -1.0079

数据集结构

a <- structure(list(study = c("Milnari", "Rajesh", "Steele", "de Graaf", 
"Chow_RT", "Steele", "Milnari", "Dux", "de Graaf", "Basile_Bcell", 
"Steele", "de Graaf", "Renshaw", "Renshaw", "Milnari", "Rajesh", 
"Steele", "Rajesh", "Rajesh", "Dux", "Ness", "Basile_Tcell", 
"Rajesh", "de Graaf", "Milnari", "Dux", "Ness", "de Graaf", "de Graaf", 
"Rajesh", "Rajesh", "Chow_RT", "Steele", "de Graaf", "Milnari", 
"Ness", "Dux", "Dux", "Ness", "Basile_Bcell", "Dux", "Milnari", 
"Renshaw", "Basile_Bcell", "Steele", "Renshaw", "Rajesh", "Rajesh", 
"Milnari", "de Graaf"), celltype = c("Lymph", "Granulo", "Granulo", 
"Mono", "WBC", "Mono", "Lymph", "Lymph", "Lymph", "Lymph", "Granulo", 
"Granulo", "WBC", "WBC", "Lymph", "WBC", "Lymph", "Granulo", 
"Granulo", "Granulo", "Lymph", "Lymph", "Granulo", "Mono", "Lymph", 
"Granulo", "Lymph", "Mono", "Granulo", "WBC", "WBC", "WBC", "Granulo", 
"Lymph", "Granulo", "Lymph", "Lymph", "Lymph", "Lymph", "Lymph", 
"Lymph", "Lymph", "WBC", "Lymph", "Granulo", "WBC", "WBC", "Granulo", 
"Granulo", "Granulo"), value = c(93L, 81L, 50L, NA, NA, NA, NA, 
88L, NA, NA, 42L, NA, 6L, NA, 93L, NA, 69L, 100L, NA, 25L, NA, 
85L, 70L, NA, NA, 10L, 80L, NA, NA, NA, 80L, 85L, NA, NA, NA, 
NA, NA, NA, NA, 75L, NA, NA, NA, NA, 48L, 30L, NA, NA, NA, 58L
), time.numeric = c(1.5, 2, 2, 4, 48, 5, 2, 0.5, 4, 2, 4, 4, 
48, 4, 1, 6, 3, 0.5, 1, 1, 24, 24, 4, 6, 48, 1.5, 1, 48, 6, 3, 
2, 1, 1.5, 2, 5, 2, 2, 5, 6, 24, 48, 2, 2, 4, 3, 24, 24, 3, 6, 
5)), class = "data.frame", row.names = c(NA, -50L))

尝试的代码

ggplot(a, aes(x = time.numeric, y = value, 
              color = study, fill = study)) +
  geom_point() +
  scale_x_continuous(trans = "log2") +
  facet_wrap(~ celltype) +
  geom_smooth(se = FALSE) 

问题原因

  • 有效数据量严重不足:value列存在大量NA,50行数据中仅4行有效数据被保留用于拟合,多数分面下的有效数据点不足2个,无法满足默认loess模型的拟合要求(loess至少需要4个数据点)。
  • 默认模型不兼容小样本:geom_smooth()默认使用loess局部回归,该方法对数据量有要求,当数据点少于模型自由度时,会触发"span too small"警告,无法生成平滑曲线。
  • 全局分组导致拟合拆分过细:全局aes中设置了color=study和fill=study,这会让geom_smooth()按study分组拟合曲线,但很多study在对应分面下只有1个有效点,根本无法完成拟合。

解决办法

1. 取消不必要的分组,拟合全局曲线

如果目标是连接分面内所有数据点(不区分study),可以在geom_smooth()中覆盖全局分组,同时更换适合小样本的线性模型:

ggplot(a, aes(x = time.numeric, y = value)) +
  geom_point(aes(color = study)) +  # 点保留study的颜色区分
  scale_x_continuous(trans = "log2") +
  facet_wrap(~ celltype) +
  geom_smooth(se = FALSE, method = "lm")  # 使用线性回归拟合

2. 预处理数据,过滤无效NA

先筛选出value非NA的行,减少无效数据干扰,再进行拟合:

a_clean <- a[!is.na(a$value), ]

ggplot(a_clean, aes(x = time.numeric, y = value, color = study)) +
  geom_point() +
  scale_x_continuous(trans = "log2") +
  facet_wrap(~ celltype) +
  geom_smooth(se = FALSE, method = "lm")

3. 按study分组拟合(需确保每组数据足够)

如果必须按study分组拟合,先检查每个celltype + study组合的有效数据量,对数据点不足的分组可以跳过拟合,或合并相似分组:

# 先查看各分组的有效数据量
table(a_clean$celltype, a_clean$study)

# 仅对数据量≥2的分组拟合
ggplot(a_clean, aes(x = time.numeric, y = value, color = study)) +
  geom_point() +
  scale_x_continuous(trans = "log2") +
  facet_wrap(~ celltype) +
  geom_smooth(se = FALSE, method = "lm", data = subset(a_clean, ave(!is.na(value), celltype, study, FUN = length) >= 2))

内容的提问来源于stack exchange,提问作者cmirian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:56:06