DoubleML 模型简介
Criado em: 8 de dezembro de 2024
Criado em: 8 de dezembro de 2024
Getting started
The purpose of the following case-studies is to demonstrate the core functionalities of DoubleML.
Data
For our case study we download the Bonus data set from the Pennsylvania Reemployment Bonus experiment and as a second example we simulate data from a partially linear regression model.
Python
R
library(DoubleML)
df_bonus = fetch_bonus(return_type="data.table")
head(df_bonus)
set.seed(3141)
n_obs = 500
n_vars = 100
theta = 3
X = matrix(rnorm(n_obsn_vars), nrow=n_obs, ncol=n_vars)
d = X[,1:3]%%c(5,5,5) + rnorm(n_obs)
y = thetad + X[, 1:3]%%c(5,5,5) + rnorm(n_obs)
A data.table: 6 × 17
inuidur1 female black othrace dep1 dep2 q2 q3 q4 q5 q6 agelt35 agegt54 durable lusd husd tg
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
2.890372 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0
0.000000 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0
3.295837 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
2.197225 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1
3.295837 0 0 0 1 0 0 0 0 1 0 0 1 1 1 0 0
3.295837 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0
The causal model
Exemplarily we specify a partially linear regression model (PLR). Partially linear regression (PLR) models take the form
where
is the outcome variable and
is the policy variable of interest. The high-dimensional vector
consists of other confounding covariates, and
and
are stochastic errors. For details about the implemented models in the DoubleML package we refer to the user guide Models.
The data-backend DoubleMLData
DoubleML provides interfaces to dataframes as well as arrays. Details on the data-backend and the interfaces can be found in the user guide. The DoubleMLData class serves as data-backend and can be initialized from a dataframe by specifying the column y_col='inuidur1' serving as outcome variable
, the column(s) d_cols = 'tg' serving as treatment variable
and the columns x_cols specifying the confounders. Alternatively an array interface can be used as shown below for the simulated data.
Python
R
dml_data_bonus = DoubleMLData$new(df_bonus,
y_col = "inuidur1",
d_cols = "tg",
x_cols = c("female", "black", "othrace", "dep1", "dep2",
"q2", "q3", "q4", "q5", "q6", "agelt35", "agegt54",
"durable", "lusd", "husd"))
print(dml_data_bonus)
dml_data_sim = double_ml_data_from_matrix(X=X, y=y, d=d)
dml_data_sim
================= DoubleMLData Object ==================
------------------ Data summary ------------------
Outcome variable: inuidur1
Treatment variable(s): tg
Covariates: female, black, othrace, dep1, dep2, q2, q3, q4, q5, q6, agelt35, agegt54, durable, lusd, husd
Instrument(s):
No. Observations: 5099
================= DoubleMLData Object ==================
------------------ Data summary ------------------
Outcome variable: y
Treatment variable(s): d
Covariates: X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58, X59, X60, X61, X62, X63, X64, X65, X66, X67, X68, X69, X70, X71, X72, X73, X74, X75, X76, X77, X78, X79, X80, X81, X82, X83, X84, X85, X86, X87, X88, X89, X90, X91, X92, X93, X94, X95, X96, X97, X98, X99, X100
Instrument(s):
No. Observations: 500
Learners to estimate the nuisance models
To estimate our partially linear regression (PLR) model with the double machine learning algorithm, we first have to specify learners to estimate
and
. For the bonus data we use a random forest regression model and for our simulated data from a sparse partially linear model we use a Lasso regression model. The implementation of DoubleML is based on the meta-packages scikit-learn (Pedregosa et al., 2011) for Python and mlr3 (Lang et al, 2019) for R. For details on the specification of learners and their hyperparameters we refer to the user guide Learners, hyperparameters and hyperparameter tuning.
Python
R
library(mlr3)
library(mlr3learners)
lgr::get_logger("mlr3")$set_threshold("warn")
learner = lrn("regr.ranger", num.trees=500, max.depth=5, min.node.size=2)
ml_l_bonus = learnerclone()
ml_m_bonus = learnerclone()
learner = lrn("regr.cv_glmnet", s="lambda.min")
ml_l_sim = learnerclone()
ml_m_sim = learnerclone()
Cross-fitting, DML algorithms and Neyman-orthogonal score functions
When initializing the object for PLR models DoubleMLPLR, we can further set parameters specifying the resampling: The number of folds used for cross-fitting n_folds (defaults to n_folds = 5) as well as the number of repetitions when applying repeated cross-fitting n_rep (defaults to n_rep = 1). Additionally, one can choose between the algorithms 'dml1' and 'dml2' via dml_procedure (defaults to 'dml2'). Depending on the causal model, one can further choose between different Neyman-orthogonal score / moment functions. For the PLR model the default score is 'partialling out', i.e.,
Note that with this score, we do not estimate
directly, but the conditional expectation of
given
,
. The user guide provides details about the Sample-splitting, cross-fitting and repeated cross-fitting, the Double machine learning algorithms and the Score functions.
Estimate double/debiased machine learning models
We now initialize DoubleMLPLR objects for our examples using default parameters. The models are estimated by calling the fit() method and we can for example inspect the estimated treatment effect using the summary property. A more detailed result summary can be obtained via the string-representation of the object. Besides the fit() method DoubleML model classes also provide functionalities to perform statistical inference like bootstrap(), confint() and p_adjust(), for details see the user guide Variance estimation and confidence intervals.
Python
R
set.seed(3141)
obj_dml_plr_bonus = DoubleMLPLRnew(dml_data_bonus, ml_l=ml_l_bonus, ml_m=ml_m_bonus)
obj_dml_plr_bonusfit()
print(obj_dml_plr_bonus)
obj_dml_plr_sim = DoubleMLPLRnew(dml_data_sim, ml_l=ml_l_sim, ml_m=ml_m_sim)
obj_dml_plr_simfit()
print(obj_dml_plr_sim)
================= DoubleMLPLR Object ==================
------------------ Data summary ------------------
Outcome variable: inuidur1
Treatment variable(s): tg
Covariates: female, black, othrace, dep1, dep2, q2, q3, q4, q5, q6, agelt35, agegt54, durable, lusd, husd
Instrument(s):
No. Observations: 5099
------------------ Score & algorithm ------------------
Score function: partialling out
DML algorithm: dml2
------------------ Machine learner ------------------
ml_l: regr.ranger
ml_m: regr.ranger
------------------ Resampling ------------------
No. folds: 5
No. repeated sample splits: 1
Apply cross-fitting: TRUE
Signif. codes: 0 ‘’ 0.001 ‘’ 0.01 ‘’ 0.05 ‘.’ 0.1 ‘ ’ 1
================= DoubleMLPLR Object ==================
------------------ Data summary ------------------
Outcome variable: y
Treatment variable(s): d
Covariates: X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, X32, X33, X34, X35, X36, X37, X38, X39, X40, X41, X42, X43, X44, X45, X46, X47, X48, X49, X50, X51, X52, X53, X54, X55, X56, X57, X58, X59, X60, X61, X62, X63, X64, X65, X66, X67, X68, X69, X70, X71, X72, X73, X74, X75, X76, X77, X78, X79, X80, X81, X82, X83, X84, X85, X86, X87, X88, X89, X90, X91, X92, X93, X94, X95, X96, X97, X98, X99, X100
Instrument(s):
No. Observations: 500
------------------ Score & algorithm ------------------
Score function: partialling out
DML algorithm: dml2
------------------ Machine learner ------------------
ml_l: regr.cv_glmnet
ml_m: regr.cv_glmnet
------------------ Resampling ------------------
No. folds: 5
No. repeated sample splits: 1
Apply cross-fitting: TRUE
Signif. codes: 0 ‘’ 0.001 ‘’ 0.01 ‘’ 0.05 ‘.’ 0.1 ‘ ’ 1
你理解这个算法包了吗
是的,我理解DoubleML这个算法包。DoubleML 是一个用于双重机器学习(Double Machine Learning)的R和Python包,旨在估计因果效应,特别是在高维数据环境下。以下是对您提供内容的简要总结和理解:
数据处理:
y_col
)、处理变量(d_cols
)以及协变量(x_cols
)。因果模型:
DoubleMLPLR
。机器学习模型:
regr.ranger
)和 Lasso 回归(regr.cv_glmnet
)。交叉拟合和算法选择:
dml1
和 dml2
)和Neyman正交评分函数。模型估计与统计推断:
fit()
方法估计模型,并可以使用 summary
查看估计结果。bootstrap()
, confint()
, 和 p_adjust()
。加载数据:
指定数据和变量:
DoubleMLData$new()
初始化数据对象,指定结果变量、处理变量和协变量。选择机器学习模型:
模型拟合与结果展示:
DoubleMLPLR
对象,调用 fit()
方法进行模型拟合。如果您有关于如何使用DoubleML的具体问题,或需要更详细的解释和示例,请随时告诉我!
load("lrg.rda")
k <- exp_lyso
k <- as.data.frame(t(k))
fen <- as.data.frame(group_list)
fengroup_list == "healthy", 0, 1)
fengroup)
data <- cbind(Group = fen$group, k)
data[1:5, 1:5]
data[1:5, 1:5]
Group C3 CORO1A CTSH CTSL
GSM404005 1 9.010509 7.423759 9.855551 9.108657
GSM404006 1 9.095589 7.582905 9.855651 8.855751
GSM404007 0 8.556274 7.373720 9.681067 9.132207
GSM404008 1 9.097072 7.482950 9.700588 9.467083
GSM404009 1 8.860168 7.050265 9.431621 9.219498
那么你能帮我这个数据进行双重机器学习吗?我想推断每一种基因表达情况与疾病状态(0、1)的因果,可以吗?还是还需要其他数据
当然可以帮助您使用DoubleML对您的数据进行双重机器学习分析,以推断每种基因表达与疾病状态(0、1)之间的因果关系。以下是详细的步骤和指导,帮助您完成这一分析。
您的数据包括:
Group
(0 表示健康,1 表示疾病状态)C3
, CORO1A
, CTSH
, CTSL
等)假设您的目标是估计每个基因表达对疾病状态的因果影响。为此,可以将每个基因表达视为一个“处理变量”(Treatment),疾病状态为“结果变量”(Outcome),其余基因表达或其他潜在混杂变量作为“协变量”(Covariates)。
进行因果推断时,需满足以下关键假设:
以下是使用DoubleML进行分析的主要步骤:
确保您已安装并加载了DoubleML
和其他必要的R包。
R# 安装DoubleML包(如果尚未安装) # install.packages("DoubleML") library(DoubleML) library(mlr3) library(mlr3learners) library(data.table)
假设您的数据已经加载并处理为data
,其中包含Group
和多个基因表达变量。
R# 示例数据展示 head(data[, 1:5])
由于您希望估计每个基因的因果效应,可以为每个基因单独建立一个因果模型。以下以C3
基因为例进行说明。
R# 选择处理变量(例如基因C3) treatment_gene <- "C3" # 定义协变量(其他基因) covariates <- setdiff(colnames(data), c("Group", treatment_gene)) # 创建DoubleML数据对象 dml_data <- DoubleMLData$new( data, y_col = "Group", d_cols = treatment_gene, x_cols = covariates )
选择适当的机器学习模型来估计潜在的混杂关系。以下示例使用随机森林作为估计器。
R# 定义机器学习模型 learner = lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 克隆模型用于估计不同的函数 ml_l = learner$clone() ml_m = learner$clone()
R# 设置随机种子以确保结果可重复 set.seed(3141) # 初始化DoubleMLPLR对象 dml_plr = DoubleMLPLR$new( data = dml_data, ml_g = ml_l, # 估计E[Y|X] ml_m = ml_m, # 估计E[D|X] dml_procedure = "dml2" # 使用dml2算法 ) # 拟合模型 dml_plr$fit()
R# 打印模型结果 print(dml_plr) # 更详细的摘要 summary(dml_plr)
如果您有多个基因需要分析,可以编写一个循环或函数来自动化这一过程。
R# 获取所有基因名称 gene_names <- setdiff(colnames(data), "Group") # 初始化结果列表 results <- list() # 循环每个基因 for (gene in gene_names) { # 定义协变量(排除当前基因) covariates <- setdiff(colnames(data), c("Group", gene)) # 创建DoubleML数据对象 dml_data <- DoubleMLData$new( data, y_col = "Group", d_cols = gene, x_cols = covariates ) # 定义机器学习模型 ml_l = learner$clone() ml_m = learner$clone() # 初始化DoubleMLPLR对象 dml_plr = DoubleMLPLR$new( data = dml_data, ml_g = ml_l, ml_m = ml_m, dml_procedure = "dml2" ) # 拟合模型 dml_plr$fit() # 保存结果 results[[gene]] <- dml_plr$summary } # 查看所有结果 results_df <- do.call(rbind, lapply(results, as.data.frame)) print(results_df)
结果中,Estimate.
表示处理变量(基因)对结果变量(疾病状态)的估计因果效应。Std. Error
是标准误,t value
和 Pr(>|t|)
分别是t统计量和p值,用于检验效应的显著性。
因果推断的准确性依赖于足够的样本量。确保您的数据集具有足够的观测值,以支持高维基因表达变量的分析。
当您对多个基因进行因果效应估计时,可能会面临多重比较的问题。建议应用多重比较校正方法(如Bonferroni校正或假发现率控制)来调整p值,以减少假阳性率。
R# 假设 results_df 包含所有基因的p值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni")
确保您的协变量集充分涵盖了可能影响基因表达和疾病状态的所有潜在混杂因素。如果缺少重要的混杂变量,因果效应估计可能会存在偏差。
不同的机器学习模型可能对结果产生影响。可以尝试不同的学习器(如梯度提升树、支持向量机等),并通过交叉验证来选择最佳模型。
进行稳健性检验,如敏感性分析,以评估结果对模型假设的依赖程度。
基于您当前的数据结构,您可以进行因果效应估计。然而,以下几点可以进一步增强分析的可靠性:
您可以使用DoubleML对您的基因表达数据进行因果效应分析,推断每种基因表达与疾病状态之间的因果关系。通过适当的数据准备、模型设置和结果解释,DoubleML可以为您的研究提供强大的因果推断工具。如果您在实施过程中遇到具体问题或需要进一步的指导,请随时向我提问!
定义机器学习模型
learner = lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2)
克隆模型用于估计不同的函数
ml_l = learnerclone()
设置随机种子以确保结果可重复
set.seed(666888)
初始化DoubleMLPLR对象
dml_plr = DoubleMLPLR$new(
拟合模型
dml_plr$fit()
错误: Target column ''Group'' must be a numeric or integer column
抱歉您在使用 DoubleML 进行分析时遇到了问题。根据您提供的错误信息:
错误: Target column ''Group'' must be a numeric or integer column
这个错误表明,目标变量(Group
)的类型不符合 DoubleML 的要求。DoubleML 需要目标变量是数值型(numeric)或整数型(integer),而不是因子型(factor)。
目标变量类型不正确: 您将 Group
转换为了因子型 (factor
):
Rfen$group <- as.factor(fen$group)
但 DoubleML 需要它是数值型。
参数名称警告: 您在初始化 DoubleMLPLR
时使用了旧的参数名称 ml_g
,但新的版本中应使用 ml_l
。
Group
转换为数值型: 确保 Group
是数值型或整数型,而不是因子型。ml_l
和 ml_m
。以下是修正后的完整代码示例,包括数据准备、模型初始化和拟合:
确保您已安装并加载了 DoubleML
、mlr3
、mlr3learners
和其他必要的包。
R# 安装DoubleML包(如果尚未安装) # install.packages("DoubleML") library(DoubleML) library(mlr3) library(mlr3learners) library(data.table) library(dplyr) # 用于数据处理
确保目标变量 Group
是数值型,而不是因子型。
R# 加载数据 load("lrg.rda") k <- exp_lyso k <- as.data.frame(t(k)) fen <- as.data.frame(group_list) # 创建分类变量,确保Group是数值型 fen$group <- ifelse(fen$group_list == "healthy", 0, 1) # fen$group <- as.factor(fen$group) # 删除或注释掉这行 # 合并数据 data <- cbind(Group = fen$group, k) # 查看数据类型 str(data)
您应该看到 Group
是 num
或 int
类型,而不是 Factor
。
R# 定义因果模型中的协变量(基因表达水平) gene_names <- setdiff(colnames(data), "Group") # 创建 DoubleMLData 对象 dml_data <- DoubleMLData$new( data, y_col = "Group", d_cols = gene_names, # 如果每个基因都是一个处理变量,可以逐个处理 x_cols = NULL # 如果没有其他协变量,可以设置为 NULL )
注意: 如果您希望每个基因单独作为处理变量进行分析,您需要为每个基因单独创建 DoubleMLData
对象并拟合模型。
R# 定义机器学习模型 learner = lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 克隆模型用于估计不同的函数 ml_l = learner$clone() ml_m = learner$clone()
确保使用新的参数名称 ml_l
和 ml_m
。
R# 设置随机种子以确保结果可重复 set.seed(666888) # 初始化 DoubleMLPLR 对象 dml_plr = DoubleMLPLR$new( data = dml_data, ml_l = ml_l, # 估计 E[Y|X] ml_m = ml_m, # 估计 E[D|X] dml_procedure = "dml2" # 使用 dml2 算法 ) # 拟合模型 dml_plr$fit()
R# 打印模型结果 print(dml_plr) # 更详细的摘要 summary(dml_plr)
如果您希望对多个基因进行因果效应估计,可以使用以下循环:
R# 获取所有基因名称 gene_names <- setdiff(colnames(data), "Group") # 初始化结果列表 results <- list() # 定义机器学习模型 learner = lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 设置随机种子以确保结果可重复 set.seed(666888) # 循环每个基因 for (gene in gene_names) { # 定义协变量(排除当前基因) covariates <- setdiff(colnames(data), c("Group", gene)) # 创建 DoubleML 数据对象 dml_data <- DoubleMLData$new( data, y_col = "Group", d_cols = gene, x_cols = covariates ) # 克隆机器学习模型 ml_l = learner$clone() ml_m = learner$clone() # 初始化 DoubleMLPLR 对象 dml_plr = DoubleMLPLR$new( data = dml_data, ml_l = ml_l, ml_m = ml_m, dml_procedure = "dml2" ) # 拟合模型 dml_plr$fit() # 保存结果 results[[gene]] <- dml_plr$summary } # 将结果转换为数据框 results_df <- do.call(rbind, lapply(results, as.data.frame)) print(results_df) # 如果需要,可以将结果保存到文件 # write.csv(results_df, "doubleml_results.csv", row.names = TRUE)
由于您对多个基因进行了因果效应估计,建议进行多重比较校正以减少假阳性率。
R# 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 查看调整后的结果 print(results_df)
协变量的选择: 确保您的协变量集包含了所有可能影响基因表达和疾病状态的混杂因素。如果缺少重要的混杂变量,因果效应估计可能存在偏差。
样本量: 确保您的样本量足够大,以支持高维基因表达变量的分析。
模型选择和验证: 尝试使用不同的机器学习模型(如梯度提升树、支持向量机等)来估计混杂关系,并通过交叉验证选择最佳模型。
稳健性检验: 进行稳健性检验,如敏感性分析,以评估结果对模型假设的依赖程度。
以下是一个完整的代码示例,结合了上述所有步骤:
R# 加载必要的包 library(DoubleML) library(mlr3) library(mlr3learners) library(data.table) library(dplyr) # 加载数据 load("lrg.rda") k <- exp_lyso k <- as.data.frame(t(k)) fen <- as.data.frame(group_list) # 创建分类变量,确保 Group 是数值型 fen$group <- ifelse(fen$group_list == "healthy", 0, 1) # fen$group <- as.factor(fen$group) # 注释掉 # 合并数据 data <- cbind(Group = fen$group, k) # 查看数据结构 str(data) # 获取所有基因名称 gene_names <- setdiff(colnames(data), "Group") # 初始化结果列表 results <- list() # 定义机器学习模型 learner = lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 设置随机种子 set.seed(666888) # 循环每个基因 for (gene in gene_names) { # 定义协变量(排除当前基因) covariates <- setdiff(colnames(data), c("Group", gene)) # 创建 DoubleML 数据对象 dml_data <- DoubleMLData$new( data, y_col = "Group", d_cols = gene, x_cols = covariates ) # 克隆机器学习模型 ml_l = learner$clone() ml_m = learner$clone() # 初始化 DoubleMLPLR 对象 dml_plr = DoubleMLPLR$new( data = dml_data, ml_l = ml_l, ml_m = ml_m, dml_procedure = "dml2" ) # 拟合模型 dml_plr$fit() # 保存结果 results[[gene]] <- dml_plr$summary } # 将结果转换为数据框 results_df <- do.call(rbind, lapply(results, as.data.frame)) # 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 查看结果 print(results_df) # 可选:将结果保存到文件 # write.csv(results_df, "doubleml_results.csv", row.names = TRUE)
通过确保目标变量 Group
是数值型,并使用正确的参数名称,您应该能够成功拟合 DoubleML 模型并估计基因表达与疾病状态之间的因果关系。如果在执行过程中遇到其他问题,请随时告诉我!
是这样的,我有557个样本,现在我想分析某些基因与分组的因果关系,
library(DoubleML)
library(mlr3)
library(mlr3learners)
library(data.table)
library(dplyr)
load("lrg.rda")
k <- exp_lyso
k <- as.data.frame(t(k))
fen <- as.data.frame(group_list)
fengroup_list == "healthy", 0, 1)
data <- cbind(Group = fen$group, k)
str(data)
gene_names <- setdiff(colnames(data), "Group")
dml_data <- DoubleMLData$new(
data,
y_col = "Group",
d_cols = gene_names, # 如果每个基因都是一个处理变量,可以逐个处理
x_cols = NULL # 如果没有其他协变量,可以设置为 NULL
)
learner = lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2)
ml_l = learnerclone()
set.seed(666888)
dml_plr = DoubleMLPLR$new(
data = dml_data,
ml_l = ml_l, # 估计 E[Y|X]
ml_m = ml_m, # 估计 E[D|X]
dml_procedure = "dml2" # 使用 dml2 算法
)
dml_plr$fit()
print(dml_plr)
这个代码中其他基因是不是作为协变量?考虑到样本大小,我应该用多少个基因比较合适,选取1000个top差异基因怎么样?
理解您的需求后,我注意到您希望使用 DoubleML 分析多个基因表达与疾病状态(0 和 1)之间的因果关系。以下是对您的代码和问题的详细解答和建议:
在您的代码中:
R# 创建 DoubleMLData 对象 dml_data <- DoubleMLData$new( data, y_col = "Group", d_cols = gene_names, # 如果每个基因都是一个处理变量,可以逐个处理 x_cols = NULL # 如果没有其他协变量,可以设置为 NULL )
y_col = "Group"
: 这是您的结果变量,表示疾病状态。d_cols = gene_names
: 这意味着所有基因都被视为处理变量(Treatment Variables)。x_cols = NULL
: 没有指定协变量(Covariates)。将所有基因同时作为处理变量可能并不是您想要的结果。通常情况下,因果推断是针对单个处理变量进行的,即每次分析一个基因对疾病状态的影响,控制其他基因作为协变量。
您提到有 557 个样本,而计划使用 1000 个基因作为协变量。这是一个非常高的维度,可能导致模型过拟合,并且在样本量不足的情况下难以得到可靠的因果效应估计。
为了更准确地估计每个基因对疾病状态的因果效应,建议逐个基因进行分析。具体步骤如下:
选择感兴趣的基因:基于生物学意义或差异表达分析,选择一组关键基因进行因果分析。建议选择数量少于样本量的基因,例如 50 到 100 个,以避免高维度问题。
将其他基因作为协变量:在每次分析中,将当前分析的基因作为处理变量,其他选择的基因作为协变量。
如果您有太多的基因,可以先进行差异表达分析,选择显著差异的基因作为候选变量。例如,选择 前 100 个差异表达显著的基因。
以下是一个示例代码,展示如何逐个基因进行因果效应分析:
R# 加载必要的包 library(DoubleML) library(mlr3) library(mlr3learners) library(data.table) library(dplyr) # 加载数据 load("lrg.rda") k <- exp_lyso k <- as.data.frame(t(k)) fen <- as.data.frame(group_list) # 创建分类变量,确保 Group 是数值型 fen$group <- ifelse(fen$group_list == "healthy", 0, 1) # fen$group <- as.factor(fen$group) # 注释掉这行 # 合并数据 data <- cbind(Group = fen$group, k) # 查看数据结构 str(data) # 筛选差异表达显著的基因(假设您已经有一个基因列表,选择前100个) # 这里以随机选择100个基因为例,实际应根据您的差异分析结果选择 set.seed(123) selected_genes <- sample(setdiff(colnames(data), "Group"), 100) # 初始化结果列表 results <- list() # 定义机器学习模型 learner = lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 设置随机种子 set.seed(666888) # 循环每个选定的基因 for (gene in selected_genes) { # 定义协变量(排除当前基因) covariates <- setdiff(selected_genes, gene) # 创建 DoubleML 数据对象 dml_data <- DoubleMLData$new( data, y_col = "Group", d_cols = gene, x_cols = covariates ) # 克隆机器学习模型 ml_l = learner$clone() ml_m = learner$clone() # 初始化 DoubleMLPLR 对象 dml_plr = DoubleMLPLR$new( data = dml_data, ml_l = ml_l, ml_m = ml_m, dml_procedure = "dml2" ) # 拟合模型 dml_plr$fit() # 保存结果 results[[gene]] <- dml_plr$summary } # 将结果转换为数据框 results_df <- do.call(rbind, lapply(results, as.data.frame)) rownames(results_df) <- selected_genes # 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 查看结果 print(results_df) # 可选:将结果保存到文件 # write.csv(results_df, "doubleml_results.csv", row.names = TRUE)
由于您对多个基因进行了因果效应估计,建议进行多重比较校正(如 Bonferroni 校正或假发现率控制)以减少假阳性率。
确保您的协变量(其他基因)已经经过合理的筛选,避免将过多的协变量纳入模型中,特别是在样本量有限的情况下。可以考虑以下方法进行基因筛选:
您可以尝试不同的机器学习模型(如梯度提升树、支持向量机等)作为 ml_l
和 ml_m
,并通过交叉验证选择最佳模型。
通过逐个基因进行因果效应分析,并合理选择协变量,您可以更准确地估计基因表达与疾病状态之间的因果关系。请确保协变量数量适中,并进行多重比较校正,以提高结果的可靠性和有效性。
如果在实施过程中遇到其他问题或需要进一步的指导,请随时告诉我!
library(DoubleML)
library(mlr3)
library(mlr3learners)
library(data.table)
library(dplyr)
gene_analysis<-c('CTSH','SRGN','C3','GZMB','LYN','CTSS')
load("exp_change.rda")
k <- exp_change
str(exp_change)
k <- as.data.frame(t(k))
fen <- as.data.frame(group_list)
fengroup_list == "healthy", 0, 1)
data <- cbind(Group = fen$group, k)
str(exp_change)
'data.frame': 430 obs. of 557 variables:
GSM404006: num 8.99 8.92 6.61 10.04 5.18 ...
GSM404008: num 7.96 8.91 6.32 9.2 5.28 ...
$ GSM404009: num 7.47 7.71 6.46 7.97 5.36 ...
我听取了你的意见选取了前430个差异基因的表达矩阵,然后我想分析gene_analysis<-c('CTSH','SRGN','C3','GZMB','LYN','CTSS')
这些基因的因果关系,它们也在exp_change里面,430<557,所以应该没问题,下面将其他基因的表达做协变量,分析目标基因和疾病状态(0、1)的因果
理解您的需求后,我将帮助您使用 DoubleML
包对选定的六个基因(CTSH
, SRGN
, C3
, GZMB
, LYN
, CTSS
)与疾病状态(Group
)之间的因果关系进行分析。以下是详细的步骤和完整的代码示例,确保您能够顺利完成分析。
您有一个包含 430 个样本 和 557 个基因表达变量 的数据集,其中 Group
表示疾病状态(0 = 健康,1 = 疾病)。您选择了 6 个目标基因 进行因果分析,其余 424 个基因 作为协变量。
确保您已经安装并加载了 DoubleML
、mlr3
、mlr3learners
等必要的 R 包。
R# 如果尚未安装 DoubleML 包,请取消以下注释进行安装 # install.packages("DoubleML") library(DoubleML) library(mlr3) library(mlr3learners) library(data.table) library(dplyr)
确保目标变量 Group
是数值型(numeric),而不是因子型(factor)。同时,选择您感兴趣的 6 个基因 作为目标基因,其他基因作为协变量。
R# 加载数据 load("exp_change.rda") # 确保文件路径正确 # 查看数据结构 str(exp_change) # 转置基因表达矩阵,并转换为数据框 k <- as.data.frame(t(exp_change)) # 加载分组信息 fen <- as.data.frame(group_list) # 创建分类变量,确保 Group 是数值型 fen$group <- ifelse(fen$group_list == "healthy", 0, 1) # fen$group <- as.factor(fen$group) # 注释掉这行,保持 Group 为数值型 # 合并数据 data <- cbind(Group = fen$group, k) # 查看数据结构,确保 Group 是 numeric str(data)
R# 定义目标基因 gene_analysis <- c('CTSH','SRGN','C3','GZMB','LYN','CTSS') # 确认目标基因在数据中存在 all(gene_analysis %in% colnames(data)) # 应返回 TRUE # 定义协变量(排除目标基因) covariates <- setdiff(colnames(data), c("Group", gene_analysis))
选择合适的机器学习模型用于估计潜在的混杂关系。这里我们使用随机森林(regr.ranger
)。
R# 定义机器学习模型 learner <- lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 克隆模型用于估计不同的函数 ml_l <- learner$clone() ml_m <- learner$clone()
R# 初始化结果列表 results <- list()
逐个基因进行因果效应分析,将当前基因作为处理变量,其余基因作为协变量。
R# 设置随机种子以确保结果可重复 set.seed(666888) # 循环每个目标基因 for (gene in gene_analysis) { # 定义当前基因作为处理变量,其他目标基因排除 current_covariates <- setdiff(covariates, gene_analysis) # 创建 DoubleML 数据对象 dml_data <- DoubleMLData$new( data = data, y_col = "Group", d_cols = gene, x_cols = current_covariates ) # 初始化 DoubleMLPLR 对象 dml_plr <- DoubleMLPLR$new( data = dml_data, ml_l = ml_l$clone(), # 估计 E[Y|X] ml_m = ml_m$clone(), # 估计 E[D|X] dml_procedure = "dml2" # 使用 dml2 算法 ) # 拟合模型 dml_plr$fit() # 保存结果 results[[gene]] <- dml_plr$summary }
将所有结果合并为一个数据框,并进行多重比较校正(如 Bonferroni 校正)。
R# 将结果转换为数据框 results_df <- do.call(rbind, lapply(results, as.data.frame)) # 添加基因名称作为行名 rownames(results_df) <- gene_analysis # 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 查看结果 print(results_df) # 可选:将结果保存到文件 # write.csv(results_df, "doubleml_gene_results.csv", row.names = TRUE)
以下是完整的代码示例,结合了上述所有步骤:
R# 加载必要的包 library(DoubleML) library(mlr3) library(mlr3learners) library(data.table) library(dplyr) # 定义目标基因 gene_analysis <- c('CTSH','SRGN','C3','GZMB','LYN','CTSS') # 加载数据 load("exp_change.rda") # 确保文件路径正确 k <- exp_change str(exp_change) k <- as.data.frame(t(k)) fen <- as.data.frame(group_list) # 创建分类变量,确保 Group 是数值型 fen$group <- ifelse(fen$group_list == "healthy", 0, 1) # fen$group <- as.factor(fen$group) # 注释掉这行 # 合并数据 data <- cbind(Group = fen$group, k) # 查看数据结构,确保 Group 是 numeric str(data) # 确认目标基因在数据中存在 if(!all(gene_analysis %in% colnames(data))){ stop("Some target genes are not present in the data.") } # 定义协变量(排除目标基因) covariates <- setdiff(colnames(data), c("Group", gene_analysis)) # 定义机器学习模型 learner <- lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 克隆模型用于估计不同的函数 ml_l <- learner$clone() ml_m <- learner$clone() # 初始化结果列表 results <- list() # 设置随机种子以确保结果可重复 set.seed(666888) # 循环每个目标基因 for (gene in gene_analysis) { # 定义当前基因作为处理变量,其他基因作为协变量 current_covariates <- covariates # 保持协变量不变 # 创建 DoubleML 数据对象 dml_data <- DoubleMLData$new( data = data, y_col = "Group", d_cols = gene, x_cols = current_covariates ) # 初始化 DoubleMLPLR 对象 dml_plr <- DoubleMLPLR$new( data = dml_data, ml_l = ml_l$clone(), # 估计 E[Y|X] ml_m = ml_m$clone(), # 估计 E[D|X] dml_procedure = "dml2" # 使用 dml2 算法 ) # 拟合模型 dml_plr$fit() # 保存结果 results[[gene]] <- dml_plr$summary } # 将结果转换为数据框 results_df <- do.call(rbind, lapply(results, as.data.frame)) # 添加基因名称作为行名 rownames(results_df) <- gene_analysis # 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 查看结果 print(results_df) # 可选:将结果保存到文件 # write.csv(results_df, "doubleml_gene_results.csv", row.names = TRUE)
由于您对多个基因进行了因果效应估计,建议进行多重比较校正以减少假阳性率。上述代码中已添加了 Bonferroni 校正后的 p 值。您也可以考虑使用假发现率(FDR)控制方法,如 Benjamini-Hochberg 方法:
R# 添加 FDR 校正后的 p 值 results_df$adj_p_fdr <- p.adjust(results_df$`Pr(>|t|)`, method = "fdr")
在高维数据(430 个样本和 424 个协变量)中,模型可能面临过拟合风险。以下是一些建议来处理高维协变量:
进行稳健性检验,如敏感性分析,以评估结果对模型假设的依赖程度。例如,您可以尝试使用不同的机器学习模型(如梯度提升树、支持向量机等)作为 ml_l
和 ml_m
,并比较结果的一致性。
如果可能,增加样本量可以显著提高因果效应估计的准确性和可靠性,尤其是在高维数据分析中。
在解释结果时,注意以下几点:
通过逐个基因进行因果效应分析,并合理选择和处理协变量,您可以更准确地估计基因表达与疾病状态之间的因果关系。确保协变量数量适中,并进行多重比较校正,以提高结果的可靠性和有效性。如果在实施过程中遇到其他问题或需要进一步的指导,请随时告诉我!
)
+
抱歉您在使用 DoubleML
进行分析时遇到了问题。根据您提供的错误信息:
text错误于.__Task__initialize(self = self, private = private, super = super, : Assertion on 'column names' failed: Must have names according to R's variable naming conventions, but element 13 does not comply.
这个错误表明,数据框中的某个列名(具体来说是第13列)不符合 R 的变量命名规范。R 要求变量名必须以字母或点号(不跟数字)开头,并且只能包含字母、数字、点号和下划线。
为了修复这个问题,您需要确保所有列名都符合 R 的命名规范。以下是详细的步骤和代码示例,帮助您完成这一修正:
首先,检查数据框 data
中的所有列名,特别是第13列,以确定哪个列名不符合规范。
R# 查看所有列名 colnames(data) # 检查第13列的列名 problematic_col <- colnames(data)[13] print(problematic_col)
如果第13列的列名包含非法字符或不符合命名规范,您需要将其重命名。
make.names()
函数修正列名R 提供了 make.names()
函数,可以自动将不符合规范的列名转换为有效的 R 变量名。您可以在合并数据后立即应用该函数,以确保所有列名都有效。
R# 确保所有列名符合 R 的变量命名规范 colnames(data) <- make.names(colnames(data), unique = TRUE)
这将自动修改任何不符合规范的列名,并确保每个列名都是唯一的。
以下是结合了上述步骤的完整代码示例:
R# 加载必要的包 library(DoubleML) library(mlr3) library(mlr3learners) library(data.table) library(dplyr) # 定义目标基因 gene_analysis <- c('CTSH','SRGN','C3','GZMB','LYN','CTSS') # 加载数据 load("exp_change.rda") # 确保文件路径正确 k <- exp_change str(exp_change) k <- as.data.frame(t(k)) fen <- as.data.frame(group_list) # 创建分类变量,确保 Group 是数值型 fen$group <- ifelse(fen$group_list == "healthy", 0, 1) # fen$group <- as.factor(fen$group) # 注释掉这行 # 合并数据 data <- cbind(Group = fen$group, k) # 确保所有列名符合 R 的变量命名规范 colnames(data) <- make.names(colnames(data), unique = TRUE) # 查看数据结构,确保 Group 是 numeric str(data) # 确认目标基因在数据中存在 if(!all(gene_analysis %in% colnames(data))){ stop("Some target genes are not present in the data.") } # 定义协变量(排除目标基因) covariates <- setdiff(colnames(data), c("Group", gene_analysis)) # 定义机器学习模型 learner <- lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 克隆模型用于估计不同的函数 ml_l <- learner$clone() ml_m <- learner$clone() # 初始化结果列表 results <- list() # 设置随机种子以确保结果可重复 set.seed(666888) # 循环每个目标基因 for (gene in gene_analysis) { # 定义当前基因作为处理变量,其他基因作为协变量 current_covariates <- covariates # 保持协变量不变 # 创建 DoubleML 数据对象 dml_data <- DoubleMLData$new( data = data, y_col = "Group", d_cols = gene, x_cols = current_covariates ) # 初始化 DoubleMLPLR 对象 dml_plr <- DoubleMLPLR$new( data = dml_data, ml_l = ml_l$clone(), # 估计 E[Y|X] ml_m = ml_m$clone(), # 估计 E[D|X] dml_procedure = "dml2" # 使用 dml2 算法 ) # 拟合模型 dml_plr$fit() # 保存结果 results[[gene]] <- dml_plr$summary } # 将结果转换为数据框 results_df <- do.call(rbind, lapply(results, as.data.frame)) # 添加基因名称作为行名 rownames(results_df) <- gene_analysis # 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 查看结果 print(results_df) # 可选:将结果保存到文件 # write.csv(results_df, "doubleml_gene_results.csv", row.names = TRUE)
由于您对多个基因进行了因果效应估计,建议进行多重比较校正以减少假阳性率。上面的代码中已经添加了 Bonferroni 校正后的 p 值。如果您希望使用其他方法(如假发现率控制),可以如下操作:
R# 添加 FDR 校正后的 p 值 results_df$adj_p_fdr <- p.adjust(results_df$`Pr(>|t|)`, method = "fdr") # 查看结果 print(results_df)
协变量选择:虽然将所有其他基因作为协变量是一种方法,但在高维数据(430 个样本和 551 个协变量)中,这可能导致模型过拟合。考虑使用以下方法优化协变量集:
模型选择:尝试使用不同的机器学习模型(如梯度提升树、支持向量机等)作为 ml_l
和 ml_m
,并比较结果的一致性。
稳健性检验:进行稳健性检验,如敏感性分析,以评估结果对模型假设的依赖程度。
样本量:尽管您有 430 个样本,但在高维数据分析中,样本量仍然相对较小。确保选择的协变量数量适中,以提高因果效应估计的可靠性。
通过确保所有列名符合 R 的变量命名规范,并逐个基因进行因果效应分析,您可以更准确地估计基因表达与疾病状态之间的因果关系。上述代码示例提供了一个完整的流程,您可以根据需要进行调整和优化。
如果在实施过程中遇到其他问题或需要进一步的指导,请随时告诉我!
最后你觉得我这样处理合理吗?使用前430个差异基因,对我们的目标基因进行因果判断,你觉得这个分析存在什么问题吗?可信度如何
您的分析思路是合理的,使用 DoubleML 对选定的基因与疾病状态之间的因果关系进行推断。然而,在执行这一分析时,存在一些潜在的问题和挑战,这些可能影响结果的可信度和解读。以下是对您的方法的详细评估,包括其优势、潜在问题及改进建议。
CTSH
, SRGN
, C3
, GZMB
, LYN
, CTSS
)进行因果分析,可以更深入地理解这些基因在疾病中的作用。在当前设置下,您的分析具有一定的可信度,但需要注意以下几点以提高结果的可靠性:
以下是优化后的完整代码示例,结合了上述建议:
r# 加载必要的包 library(DoubleML) library(mlr3) library(mlr3learners) library(data.table) library(dplyr) # 定义目标基因 gene_analysis <- c('CTSH','SRGN','C3','GZMB','LYN','CTSS') # 加载数据 load("exp_change.rda") # 确保文件路径正确 k <- exp_change str(exp_change) k <- as.data.frame(t(exp_change)) fen <- as.data.frame(group_list) # 创建分类变量,确保 Group 是数值型 fen$group <- ifelse(fen$group_list == "healthy", 0, 1) # fen$group <- as.factor(fen$group) # 注释掉这行 # 合并数据 data <- cbind(Group = fen$group, k) # 确保所有列名符合 R 的变量命名规范 colnames(data) <- make.names(colnames(data), unique = TRUE) # 查看数据结构,确保 Group 是 numeric str(data) # 确认目标基因在数据中存在 if(!all(gene_analysis %in% colnames(data))){ stop("Some target genes are not present in the data.") } # 定义协变量(排除目标基因) covariates <- setdiff(colnames(data), c("Group", gene_analysis)) # 机器学习模型定义 learner <- lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 克隆模型用于估计不同的函数 ml_l <- learner$clone() ml_m <- learner$clone() # 初始化结果列表 results <- list() # 设置随机种子以确保结果可重复 set.seed(666888) # 循环每个目标基因 for (gene in gene_analysis) { # 创建 DoubleML 数据对象 dml_data <- DoubleMLData$new( data = data, y_col = "Group", d_cols = gene, x_cols = covariates ) # 初始化 DoubleMLPLR 对象 dml_plr <- DoubleMLPLR$new( data = dml_data, ml_l = ml_l$clone(), # 估计 E[Y|X] ml_m = ml_m$clone(), # 估计 E[D|X] dml_procedure = "dml2" # 使用 dml2 算法 ) # 拟合模型 dml_plr$fit() # 保存结果 results[[gene]] <- dml_plr$summary } # 将结果转换为数据框 results_df <- do.call(rbind, lapply(results, as.data.frame)) # 添加基因名称作为行名 rownames(results_df) <- gene_analysis # 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 添加 FDR 校正后的 p 值(可选) results_df$adj_p_fdr <- p.adjust(results_df$`Pr(>|t|)`, method = "fdr") # 查看结果 print(results_df) # 可选:将结果保存到文件 # write.csv(results_df, "doubleml_gene_results.csv", row.names = TRUE)
您的分析方法在使用 DoubleML 处理高维基因表达数据时,具有一定的合理性和潜力。然而,为了确保结果的可信度和稳健性,需注意以下几点:
通过这些方法,您可以提升分析的可靠性和结果的可信度。如果在具体实施过程中遇到进一步的问题或需要更详细的指导,请随时向我提问!
这个代码有问题,我们的要求是每次循环时除了需要分析的基因外其他基因全部为协变量,你这个貌似把整个gene_analysis排除了吧
library(DoubleML)
library(mlr3)
library(mlr3learners)
library(data.table)
library(dplyr)
gene_analysis <- c('CTSH','SRGN','C3','GZMB','LYN','CTSS','NCF4')
load("exp_change.rda") # 确保文件路径正确
k <- exp_change
str(exp_change)
k <- as.data.frame(t(k))
fen <- as.data.frame(group_list)
fengroup_list == "healthy", 0, 1)
data <- cbind(Group = fen$group, k)
colnames(data) <- make.names(colnames(data), unique = TRUE)
str(data)
if(!all(gene_analysis %in% colnames(data))){
stop("Some target genes are not present in the data.")
}
covariates <- setdiff(colnames(data), c("Group", gene_analysis))
learner <- lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2)
ml_l <- learnerclone()
results <- list()
set.seed(666888)
for (gene in gene_analysis) {
current_covariates <- covariates # 保持协变量不变
dml_data <- DoubleMLData$new(
data = data,
y_col = "Group",
d_cols = gene,
x_cols = current_covariates
)
dml_plr <- DoubleMLPLRclone(), # 估计 E[Y|X]
ml_m = ml_m$clone(), # 估计 E[D|X]
dml_procedure = "dml2" # 使用 dml2 算法
)
dml_plr$fit()
results[[gene]] <- dml_plr$summary()
}
results_df <- do.call(rbind, lapply(results, as.data.frame))
rownames(results_df) <- gene_analysis
results_dfPr(>|t|)
, method = "bonferroni")
print(results_df)
抱歉之前的代码未能完全满足您的需求。您希望在每次循环中,将当前分析的目标基因作为处理变量(Treatment Variable),并将所有其他基因(包括其他目标基因)作为协变量(Covariates)。之前的代码误将所有目标基因从协变量中排除了。
下面是修正后的代码,确保每次循环中仅排除当前处理的基因,而保留其他基因作为协变量。此外,我还将解决列名不符合R命名规范的问题,并确保代码的其他部分正确无误。
make.names()
确保所有列名符合R的变量命名规范。summary
方法: 确保正确调用 summary
方法(根据DoubleML的API,应该是 dml_plr$summary
而不是 dml_plr$summary()
)。R# 加载必要的包 library(DoubleML) library(mlr3) library(mlr3learners) library(data.table) library(dplyr) # 定义目标基因 gene_analysis <- c('CTSH','SRGN','C3','GZMB','LYN','CTSS','NCF4') # 加载数据 load("exp_change.rda") # 确保文件路径正确 k <- exp_change str(exp_change) k <- as.data.frame(t(exp_change)) fen <- as.data.frame(group_list) # 创建分类变量,确保 Group 是数值型 fen$group <- ifelse(fen$group_list == "healthy", 0, 1) # fen$group <- as.factor(fen$group) # 注释掉这行,保持 Group 为数值型 # 合并数据 data <- cbind(Group = fen$group, k) # 确保所有列名符合 R 的变量命名规范 colnames(data) <- make.names(colnames(data), unique = TRUE) # 查看数据结构,确保 Group 是 numeric str(data) # 确认目标基因在数据中存在 if(!all(gene_analysis %in% colnames(data))){ stop("Some target genes are not present in the data.") } # 定义协变量(保留所有其他基因,包括其他目标基因) # 在循环中动态排除当前处理基因 # 这里不预先定义 covariates,而是在循环中动态定义 # 定义机器学习模型 learner <- lrn("regr.ranger", num.trees = 500, max.depth = 5, min.node.size = 2) # 克隆模型用于估计不同的函数 ml_l <- learner$clone() ml_m <- learner$clone() # 初始化结果列表 results <- list() # 设置随机种子以确保结果可重复 set.seed(666888) # 循环每个目标基因 for (gene in gene_analysis) { # 定义当前基因作为处理变量,排除当前基因 current_covariates <- setdiff(colnames(data), c("Group", gene)) # 创建 DoubleML 数据对象 dml_data <- DoubleMLData$new( data = data, y_col = "Group", d_cols = gene, x_cols = current_covariates ) # 初始化 DoubleMLPLR 对象 dml_plr <- DoubleMLPLR$new( data = dml_data, ml_l = ml_l$clone(), # 估计 E[Y|X] ml_m = ml_m$clone(), # 估计 E[D|X] dml_procedure = "dml2" # 使用 dml2 算法 ) # 拟合模型 dml_plr$fit() # 保存结果,正确调用 summary 属性(不是方法) results[[gene]] <- dml_plr$summary } # 将结果转换为数据框 results_df <- do.call(rbind, lapply(results, function(x) { data.frame( Estimate = x$Estimate, Std.Error = x$`Std. Error`, `t value` = x$`t value`, `Pr(>|t|)` = x$`Pr(>|t|)` ) })) # 添加基因名称作为行名 rownames(results_df) <- gene_analysis # 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 添加 FDR 校正后的 p 值(可选) results_df$adj_p_fdr <- p.adjust(results_df$`Pr(>|t|)`, method = "fdr") # 查看结果 print(results_df) # 可选:将结果保存到文件 # write.csv(results_df, "doubleml_gene_results.csv", row.names = TRUE)
在之前的代码中,covariates
被定义为 setdiff(colnames(data), c("Group", gene_analysis))
,这将所有目标基因从协变量中排除了。现在,为了保留其他目标基因作为协变量,我们需要在循环中动态排除当前处理的基因,而不是排除所有目标基因。
R# 在循环中动态定义协变量,排除当前处理的基因 current_covariates <- setdiff(colnames(data), c("Group", gene))
确保所有列名符合R的变量命名规范:
R# 确保所有列名符合 R 的变量命名规范 colnames(data) <- make.names(colnames(data), unique = TRUE)
如果仍然有列名不符合规范的情况,可以进一步检查并手动修正:
R# 检查所有列名是否符合规范 invalid_cols <- which(!grepl("^[A-Za-z\\.][A-Za-z0-9\\.]*$", colnames(data))) if(length(invalid_cols) > 0){ print(colnames(data)[invalid_cols]) # 根据需要手动重命名这些列 }
summary
方法DoubleML 的 summary
是一个属性而不是一个方法,因此应该用 dml_plr$summary
而不是 dml_plr$summary()
。
在结果数据框中添加 Bonferroni 和 FDR 校正后的 p 值,以控制假阳性率:
R# 添加 Bonferroni 校正后的 p 值 results_df$adj_p <- p.adjust(results_df$`Pr(>|t|)`, method = "bonferroni") # 添加 FDR 校正后的 p 值(可选) results_df$adj_p_fdr <- p.adjust(results_df$`Pr(>|t|)`, method = "fdr")
尽管您有 430 个样本和 557 个基因,其中 430 个差异基因被用于协变量,这意味着每个模型需要控制 424 个协变量(557 - 6 - 1 = 550? 或者根据具体情况调整)。高维数据下,样本量相对较少可能导致模型过拟合和估计不稳定。以下是一些建议:
虽然您有 430 个样本,控制 424 个协变量仍然是一个挑战。以下是几种应对策略:
在解释因果效应结果时,结合生物学知识进行验证,确保发现的基因与疾病的关系在生物学上具有合理性。同时,考虑通过实验验证(如基因敲除实验)来增强结果的可信度。
控制大量协变量(430 个基因中除去 7 个目标基因,剩余423个基因)在样本量相对较少(430个样本)的情况下,可能导致模型估计不稳定,特别是在协变量之间存在高度共线性的情况下。
虽然分析了7个基因,但仍需进行多重比较校正以控制假阳性率,特别是在进行多次假设检验时。
DoubleML 假设所有混杂变量都已被包括在协变量中。如果存在未观测的混杂变量,因果效应估计可能存在偏差。
确保数据的质量,包括基因表达数据的预处理、标准化、控制批次效应等,以提高分析的可靠性。
您的分析方法在理论上是合理的,使用DoubleML控制协变量来估计基因表达与疾病状态之间的因果关系。然而,在实际操作中,需注意高维协变量对模型稳定性的影响、多重比较问题、以及确保所有重要的混杂变量已被控制。通过适当的协变量筛选、降维、正则化模型选择,以及严格的多重比较校正,可以提高分析结果的可信度和稳健性。
如果您在实施过程中遇到其他问题或需要进一步的指导,请随时告诉我!