如何用lapply循环执行rda回归与ordiR2step函数?
问题与解决方案
问题背景
有一个数据集,需要每72行执行一次rda函数(共执行10次),参考lapply用法尝试循环执行回归时出错;同时将该方法应用于ordiR2step函数也未成功。
原始代码与报错
set.seed(111) df <- data.frame(sp1 = rep(rtruncnorm(10, a=0, b=1, mean = 0.50, sd = 0.2), times = 10), sp2 = rep(rtruncnorm(10, a=0, b=1, mean = 0.70, sd = 0.1), times = 10), env1 = rep(rtruncnorm(10, a=0, b=1, mean = 0.45, sd = 0.6), times = 10), env2 = rep(rtruncnorm(10, a=0, b=1, mean = 0.65, sd = 0.6), times = 10) ) library(vegan) spe.rda <- rda(df[,c(1:2)] ~ ., data = df[,c(3:4)]) # 单独执行正常 # 尝试按seed分组循环执行rda spe.rda <- lapply(split(df[1:4], df$seed), rda(df[,c(1:2)] ~ ., data = df[,c(3:4)]))
Error in match.fun(FUN) :
'rda(df[, c(1:2)] ~ ., data = df[, c(3:4)])' is not a function, character or symbol
尝试ordiR2step的错误代码:
output <- lapply(split(df[1:4], df$seed), ordiR2step(rda(df[,c(1:2)]~1, data=df[,c(3:4)]), scope= formula(spe.rda), direction= "forward", R2scope=TRUE, pstep=1000)) # 显然无法运行,因为依赖spe.rda
错误原因
lapply第二个参数需为函数对象,但你直接传入了rda()的执行结果(模型对象),不符合参数要求。- 数据集缺少分组标识列(
df$seed不存在),无法按预期拆分数据。 ordiR2step需针对每个分组单独构建初始模型和范围,不能直接引用全局模型。
修正后的代码
步骤1:添加分组标识
先给数据集添加分组列,按每72行一组(示例用每10行一组模拟10组):
library(vegan) library(truncnorm) set.seed(111) df <- data.frame(sp1 = rep(rtruncnorm(10, a=0, b=1, mean = 0.50, sd = 0.2), times = 10), sp2 = rep(rtruncnorm(10, a=0, b=1, mean = 0.70, sd = 0.1), times = 10), env1 = rep(rtruncnorm(10, a=0, b=1, mean = 0.45, sd = 0.6), times = 10), env2 = rep(rtruncnorm(10, a=0, b=1, mean = 0.65, sd = 0.6), times = 10) ) # 创建分组列:每10行一组(替换为each=72即可满足你的需求) df$group <- rep(1:10, each = 10)
步骤2:循环执行rda
使用匿名函数针对每个分组数据执行rda:
# 按分组拆分并循环执行rda spe.rda_list <- lapply(split(df, df$group), function(sub_df) { rda(sub_df[, c(1:2)] ~ ., data = sub_df[, c(3:4)]) }) # 查看第一个分组的rda结果 spe.rda_list[[1]]
步骤3:循环执行ordiR2step
针对每个分组单独构建初始模型和范围,再执行逐步选择:
# 循环执行ordiR2step ordi_step_list <- lapply(split(df, df$group), function(sub_df) { # 构建仅含截距的初始模型 initial_rda <- rda(sub_df[, c(1:2)] ~ 1, data = sub_df[, c(3:4)]) # 构建模型范围:从仅截距到全变量模型 scope_formula <- formula(rda(sub_df[, c(1:2)] ~ ., data = sub_df[, c(3:4)])) # 执行逐步选择 ordiR2step(initial_rda, scope = scope_formula, direction = "forward", R2scope = TRUE, pstep = 1000) }) # 查看第一个分组的逐步选择结果 ordi_step_list[[1]]
关键说明
lapply的第二个参数必须是函数,匿名函数function(sub_df) {...}可让每个分组数据作为参数传入,确保分析基于当前子数据集。- 所有操作需针对分组后的子数据进行,避免引用全局数据或模型,否则会失去循环意义。
内容的提问来源于stack exchange,提问作者Rspacer
相关产品推荐
相关产品推荐

