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

非配对数据关联分析方法探讨——含土壤样本实例

非配对土壤样本的变量关联分析问题与解决方案

问题背景

需要结合采样点(location)开展不同土壤类型间的变量关联分析,但各土壤类型在同一采样点的样本数量不一致,属于非配对数据。尝试两种方法均存在问题:通过inner_join强制配对会导致观测值重复,疑似引入偏差;按采样点取均值实现配对则会丢失样本变异信息,且两种方法的关联结果差异显著。

示例数据

df <- structure(list(location = c("A", "A", "A", "A", "B", "B", "B","B", "C", "C", "C", "C", "C", "C", "D", "D"), 
                     type_of_soil = c("type1", "type1", "type2", "type3", "type1", "type2", "type2", "type3", "type1", "type2", "type2", "type2", "type3", "type3", "type1", "type2"), 
                     var1 = c(29, 7, 11, 20, 12, 15, 22, 27, 29, 32, 31, 23, 22, 20, 20, 15), 
                     var2 = c(56, 92, 111, 15, 230, 23, 47, 50, 190, 10, 6, 2, 15, 73, 223, 50), 
                     var3 = c(1000, 1643, 1242, 6352, 111, 3552, 837, 5612, 999, 572, 127, 593, 3232, 524, 41, 2)), 
                class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -16L))

两种尝试方法的问题分析

方法1:宽格式转换+inner_join强制配对

用户先将数据转为宽格式,再编写函数通过inner_join按采样点配对:

df$ID <- 1:nrow(df) # 为每个原始样本分配ID
df_longer <- pivot_longer(data = df, cols = -c(1,2,6) , names_to = "var", values_to = "vals")
df_cor <- unite(df_longer, var, type_of_soil, sep = '_', col = 'var_type')
df_wider <- pivot_wider(df_cor, names_from = var_type, values_from = vals)

bicorplot <- function(df_forcor, soil1, soil2){
  coord1 <- grep(soil1, colnames(df_forcor))
  coord2 <- grep(soil2, colnames(df_forcor))
  
  df1 <- na.omit(df_forcor[,c(1, coord1)])
  df2 <- na.omit(df_forcor[,c(1, coord2)])
  
  coord_eq1 <- df1[df1$location %in% df2$location,]
  coord_eq2 <- df2[df2$location %in% df1$location,]
  
  temp_df <- inner_join(coord_eq1, coord_eq2, by = "location")
  temp_df1 <- temp_df[1:4]
  temp_df2 <- temp_df[c(1,5:7)]
  
  cor_mat <- cor(x = temp_df1[2:4], y = temp_df2[2:4], method = "spearman")
  
  corrplot(cor_mat)
}

核心问题:当同一采样点下某土壤类型存在多个样本时,inner_join会生成笛卡尔积式的重复观测。例如某采样点有2个type1样本和2个type3样本,配对后会生成4行数据,该采样点的权重被放大4倍,直接扭曲了关联分析的结果,引入严重偏差。

方法2:按采样点取均值后分析

用户先按采样点合并均值,再进行关联分析:

df_mean <- df_wider %>%
  group_by(location) %>%
  summarise_all(mean, na.rm = T)

bicorplot(df_wider, 'type1', 'type3')
bicorplot(df_mean, 'type1', 'type3')

核心问题:取均值会完全丢失同一采样点内的样本变异信息,而这些变异往往包含变量关联的关键细节。同时,若不同采样点的样本数量差异较大,均值会被样本多的采样点过度主导,导致关联结果过于平滑,无法反映真实的变量关系。


正确分析思路:考虑采样点聚类的混合效应/稳健关联分析

由于数据存在嵌套结构(采样点下包含多个不同土壤类型的样本),需控制采样点带来的组内非独立性,避免偏差。推荐两种严谨的方法:

方法1:混合效应模型(推荐)

使用混合效应模型将采样点作为随机效应,控制组内变异,直接在原始数据上分析变量关联:

library(lme4)
library(dplyr)
library(tidyr)

# 筛选同时包含两种目标土壤类型的采样点
valid_locs <- df %>%
  group_by(location) %>%
  filter(all(c("type1", "type3") %in% type_of_soil)) %>%
  pull(location) %>%
  unique()

# 提取目标数据并转为配对宽格式
df_paired <- df %>%
  filter(location %in% valid_locs, type_of_soil %in% c("type1", "type3")) %>%
  pivot_wider(
    names_from = type_of_soil,
    values_from = c(var1, var2, var3),
    names_sep = "_"
  )

# 构建混合效应模型,以location为随机截距
model_var1 <- lmer(var1_type1 ~ var1_type3 + (1|location), data = df_paired)
summary(model_var1)

# 批量分析所有变量对并可视化
cor_mat <- sapply(c("var1", "var2", "var3"), function(v1) {
  sapply(c("var1", "var2", "var3"), function(v2) {
    formula <- as.formula(paste0(v1, "_type1 ~ ", v2, "_type3 + (1|location)"))
    coef(summary(lmer(formula, data = df_paired)))[2,1]
  })
})

corrplot::corrplot(cor_mat, method = "color", title = "混合效应模型下的变量关联系数")

方法2:稳健聚类关联分析

使用psych包的corr.test函数,指定采样点为聚类变量,控制非独立性:

library(psych)
library(corrplot)

# 生成所有土壤类型配对的观测数据
df_pair <- inner_join(
  df %>% filter(type_of_soil == "type1") %>% rename_with(~paste0(., "_type1"), starts_with("var")),
  df %>% filter(type_of_soil == "type3") %>% rename_with(~paste0(., "_type3"), starts_with("var")),
  by = "location"
)

# 执行聚类稳健的关联分析
corr_result <- corr.test(
  df_pair %>% select(starts_with("var")),
  cluster = df_pair$location,
  method = "spearman"
)

# 可视化结果
corrplot(corr_result$r, p.mat = corr_result$p, sig.level = 0.05, insig = "blank")

内容的提问来源于stack exchange,提问作者Igor Salerno Filgueiras

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:24:59