ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

lavaan跑生态学SEM:非线性、缺失值与空间自相关实战指南

lavaan跑生态学SEM:非线性、缺失值与空间自相关实战指南 两年前我第一篇SEM图放进生态学论文修改稿时审稿人给了一句很常见的意见建议用结构方程模型进一步检验变量间的直接和间接效应。当时我以为这只是走个过场用回归加路径图糊弄一下就行。结果从SPSS Amos换到R语言lavaan再到处理非线性、缺失值、空间自相关整整折腾了两个月。这篇文章就把这些坑和解决方法一次说清楚尤其是生态学数据里绕不开的非线性关系和空间自相关到底怎么在lavaan里落地又怎么在Nature子刊级别的审稿流程里站住脚。如果你正在用lavaan做生态SEM或者准备把SEM写进投稿论文这篇文章应该能帮你少走一半弯路。我会从模型选型、非线性处理、缺失值策略、空间自相关建模到最后的方法部分怎么写完整过一遍。1. 生态学数据用lavaan跑SEM和教科书里的SEM根本不是一回事1.1 生态学数据为什么让SEM水土不服SEM最早是从心理计量学发展来的经典场景是几百上千份问卷一个潜变量背后有3-5个题项数据干净、分布良好、样本独立。但生态学数据完全不是这个画风变量来自野外样方调查、遥感反演、气象插值、实验室测定每种数据的获取方式、误差来源、空间尺度都不一样。50个样方的观测值可能只有10个土壤变量是完整的植物多样性数据缺了8个而气候数据是从网格插值里提取的天然存在空间平滑效应。这个差异造成的第一个影响是生态SEM很少用测量模型。大部分情况下我们处理的是观测变量比如年均温、土壤全氮、Shannon多样性直接建立回归路径不会去搞潜变量。好处是模型简单、收敛快、不容易出现Heywood case坏处是测量误差完全暴露在路径系数里对数据质量的要求反而更高。第二个影响是分布类型五花八门。物种丰富度是计数数据土壤pH基本对称多样性指数往往在0-3之间偏斜而生产力数据经常有离群值。这些变量放进同一个SEM里光标准化这一步就够讨论半天的。lavaan默认的ML估计法对多元正态性有要求如果你直接拿偏斜严重的原始数据跑模型拟合指数大概率很难看但这不代表你的科学假设是错的可能只是估计方法不合适。后面我会专门说怎么用稳健估计和Bootstrap来处理。1.2 lavaan与piecewiseSEM的选型问题都是R包差别很大生态学圈子里part of SEM分析piecewiseSEM也很有名。这两个包在思路上有本质区别选错可能直接影响你的论文能不能过审。对比维度lavaanpiecewiseSEM估计策略全局估计一次性拟合所有方程局部估计每条方程独立拟合再合并全局拟合指数有CFI/TLI/RMSEA/SRMR等无基于d-sep的Fishers C统计量潜变量支持强弱主要面向路径模型非线性处理可手动构造多项式、样条基可在线性模型框架内扩展缺失值内置FIML需要预先处理数据空间自相关需自行纳入空间变量可嵌套随机效应天然适合层次/空间数据复杂随机效应不支持支持我的经验是如果你的科研问题是多个变量的直接、间接效应同时存在而且样本量在50-300之间lavaan的全局拟合指标会让审稿人更安心。Nature Ecology Evolution这类期刊的审稿人已经熟悉CFI/RMSEA这套语系你给他们看Fishers C反而容易产生理解成本。但如果你的数据结构复杂、有明显空间分层、而且没打算做潜变量piecewiseSEM可能更稳健。这篇博文我集中讲lavaan因为它在非线性、缺失值处理上都有官方解决方案更容易写进方法部分。另外还有semTools包可以补充Bootstrap置信区间和群组不变性检验对生态学对比研究比如不同生态系统类型间的路径差异非常有帮助。下面五节的内容全部围绕lavaan展开。2. 非线性关系进SEM从多项式到样条lavaan里的三种写法2.1 为什么生态SEM里非线性躲不掉生态学关系的经典形式本来就不是直线。物种多样性与生产力的关系经常是单峰曲线在中等生产力水平达到最高多样性捕食者-猎物关系常见饱和效应土壤水分对植物生长的效应有一个最适区间低于或高于阈值都会下降。如果你把这些关系硬写成线性路径会出现两个后果第一残差有明显结构拟合指数崩掉第二也是更要命的路径系数可能被平均效应掩盖原本显著的中间区间效应变得不显著你的科学故事就丢了。所以在构建SEM之前我建议对每一对关键关系先画散点图并拟合gam或lowess曲线。如果看到明显弯曲你不能假装看不见得把它放进模型。下面说三种在lavaan里实现非线性的方法难度递增。2.2 方法一多项式回归最省事的显式曲线lavaan模型语法支持在变量名上做函数变换二次项可以用I(x^2)直接写进方程model - div ~ prod I(prod^2) climate prod ~ climate soil fit - sem(model, data dat)这里有一个非常重要的细节必须对prod做中心化处理否则prod和prod^2会高度相关导致估计不稳定、标准误爆炸。中心化之后prod的回归系数代表生产力平均水平处的斜率I(prod^2)的系数代表弯曲程度解释起来也更有意义。dat$prod_c - scale(dat$prod, center TRUE, scale FALSE)[, 1] dat$prod_c2 - dat$prod_c^2如果是观测变量之间的交互项比如气候调节土壤对多样性的效应写法是model - div ~ soil climate soil:climate lavaan会自动创建交互项但记得同样先把soil和climate中心化。要是模型里有潜变量交互事情会麻烦一些需要用x1:x2定义乘积指标。生态学SEM用潜变量交互的概率不高这里就不展开了。多项式方法最大的问题是它假设曲线是全局对称的二次项只能表达一个极值点。如果你的关系是先上升后平台的饱和曲线或者两侧低中间高但不对称多项式会拟合得很勉强。这时候上样条。2.3 方法二样条进lavaan的两条路线lavaan的语法解析器支持有限你没法直接在模型语句里写splines::ns(x, df3)然后指望summary输出漂亮的系数。我常用的做法是在进入lavaan之前先用model.matrix把样条基算出来然后作为多个预测变量放进模型。library(splines) # 生成样条基矩阵 ns_mat - ns(dat$prod, df 3) # 3个自由度内部默认两个节点 colnames(ns_mat) - paste0(prod_ns, 1:3) dat - cbind(dat, ns_mat) # 写lavaan模型把原始prod替换成三列样条基 model_spline - div ~ prod_ns1 prod_ns2 prod_ns3 climate prod ~ climate soil fit_spline - sem(model_spline, data dat)样条方法解释起来确实没有多项式直观因为你得到的是三四个系数而不是一个二次项系数。但它在拟合复杂曲线时非常灵活而且你可以通过比较加入样条前后的模型拟合AIC、似然比检验证明非线性存在的必要性。如果希望曲线更平滑可以增加ns()的自由度但要留意过拟合。生态学样本量往往不大3个自由度一般够用再多模型就不稳定了。样条基的另一个好处是可以扩展到空间维度处理空间自相关时还能顺手做空间样条后面第四节会再提。2.4 方法三分段回归/阈值模型lavaan里的手工变通阈值效应比如温度超过一定值后效应方向改变在生态学里非常常见。lavaan没有内置分段回归但你可以用ifelse构造分段变量dat$temp_above - ifelse(dat$temp 12, dat$temp - 12, 0) model - div ~ temp temp_above soil 这里有一个细微但关键的统计问题temp的系数代表低于阈值时每升温1度的效应斜率temp_above的系数代表超过阈值后额外增加的斜率两者相加才是高温段的真实斜率。阈值这里是12度最好从数据里通过分段回归或生长曲线模型预先估计而不是拍脑袋定否则属于数据窥探审稿人会揪。阈值模型的替代方案是使用brms做贝叶斯SEM但那是另一个框架了。如果你跟审稿人解释不清阈值怎么来的建议回到样条路线因为样条不需要指定节点位置显得更客观。2.5 非线性模型的结果解读和拟合检验不管用了哪种非线性形式都要做两件事第一和线性基线模型比较说明非线性的增量价值第二画出条件效应图让审稿人一眼看到曲线形态。# 用anova比较线性模型和二次模型的拟合差异 fit_linear - sem(div ~ prod climate, data dat) fit_quad - sem(div ~ prod I(prod^2) climate, data dat) anova(fit_linear, fit_quad) # lavPredict得到预测值后画图 pred - lavPredict(fit_quad)如果anova显示二次模型显著更好就在论文里写引入二次项后模型拟合显著改善ΔAIC ...P 0.05表明生产力与多样性之间存在单峰关系。记住AIC比较在生态学SEM里几乎是标配不要只给路径系数。3. 缺失值不可怕可怕的是你还用listwise deletion3.1 生态学数据缺失的三个典型场景生态学野外数据的缺失几乎不可避免。最常见的三个来源一是传感器故障或设备维护比如土壤水分探头在雨季被淹导致连续两周无记录二是极端天气或野生动物破坏某个样方的植被调查被迫跳过三是不同测量平台的时间不同步植物在6月测、土壤在8月采融合成一张表后自然出现缺失。更麻烦的是缺失往往不是完全随机的——样方越难到达数据越可能缺失这就是非随机缺失。很多人的第一反应是na.omit把有缺失的样方整行删掉。这在缺失率低、缺失完全随机的情况下问题不大但生态学数据常常是缺失率10%-30%而且和变量本身或空间位置有关。整行删除会让你的有效样本量锐减还会引入样本选择偏差路径系数就可能失真。这就是为什么lavaan的FIML选项值得优先考虑。3.2 lavaan的FIML原理和设置一行代码的事lavaan对缺失值处理的支持非常优雅在sem()函数里加一个参数就行fit - sem(model, data dat, missing ml)这个ml就是全信息极大似然Full Information Maximum Likelihood, FIML。它的核心思想很简单模型估计时不删除任何行而是对每个观测使用所有可用的变量信息来估计。缺失变量的那一部分通过期望最大化算法迭代补全最后得到的是在所有可用信息条件下的极大似然估计。本质上它比均值填补、回归填补都更稳健因为它自动考虑了变量之间的协方差结构。FIML的统计学前提是数据满足MARMissing at Random即缺失概率只取决于已观测变量而不取决于缺失值本身。比如土壤样本因为样点太陡没采到而这个陡峭度可能和海拔、坡度等有关只要这些变量在模型里FIML就能有效校正。如果缺失与缺失值本身有关MNAR那就需要用选择模型或双重稳健方法但那已经超出常规SEM范畴了。使用FIML后有一个直观变化不同变量的样本量不一致不再影响拟合输出的n.total表示总的观测行数。报告中要写明missing data were handled by full information maximum likelihood under the missing-at-random assumption这句话审稿人很吃这一套。3.3 FIML和多重插补怎么选缺失率说了算FIML不是唯一的优质选择多重插补Multiple Imputation, MI在生态学里也很常用。我个人的分界线是缺失率低于20%、缺失模式相对简单、主要变量缺失不超过15%时FIML够用缺失率超过20%、多个关键变量都有大量缺失时用mice多重插补更稳妥。多重插补的流程是三步先用mice生成若干份完整数据比如20份再对每份数据跑lavaan最后用semTools::runMI合并结果library(mice) library(semTools) imp - mice(dat, m 20, method pmm, seed 123) fit_mi - runMI(model, data dat, fun sem, m 20, miArgs list(missing ml))注意runMI是semTools包专门为lavaan准备的多重插补包装函数它会自动完成插补-拟合-合并的流程输出合并后的参数估计、标准误和拟合指数。合并规则遵循Rubins rules标准误会同时包含插补内部和插补之间的变异比单次插补更诚实。我踩过的坑是用mice默认的pmm方法处理计数变量时插补值可能出现负数或小数物种丰富度变成7.3这种数字解释起来很尴尬。解决办法是对计数变量用poisson或sample方法或者插补后再取整。另外插补时最好把模型中所有变量都放进去包括那些不在方程里但和缺失机制相关的辅助变量这样MAR假设更容易满足。3.4 FIML实际使用中的两个怪现象用FIML之后有两次让我差点怀疑是bug其实是lavaan的正常行为。第一很多拟合指数会消失或变成缺失值尤其是SRMR和summary里的一部分统计量因为FIML没有传统意义上的再现协方差矩阵部分指标确实无法计算。报告时可以说CFI 0.96, RMSEA 0.04略过SRMR不写这不丢人很多人不知道这个原理。第二标准化系数在FIML下可能会比listwise deletion时更显著这是正常的因为更多信息参与估计标准误变小了。但如果你发现某个系数出现离谱的变异比如路径系数超过1.5甚至方向翻转记得检查是不是缺失率太高导致模型识别不足这时应该退回多重插补或者减少变量数。4. 空间自相关混进SEM结果可能全是假信号4.1 空间自相关为什么是SEM里的隐形混淆变量生态学数据几乎没有空间独立的。相邻样方的气候、土壤、物种组成都很像这不是巧合而是生态学的基本属性——环境梯度、扩散过程、历史效应都会在空间上产生自相关。问题是SEM假设观测是独立的如果你的两个变量同时受地理距离驱动比如纬度和温度、海拔和降水它们的相关系数里有一部分其实是空间相似性造成的伪相关。最后跑出来的路径系数可能显著但科学解释可能是错的。我处理过最典型的一个例子在某山地的90个样方里海拔和土壤有机碳的相关系数高达0.78但把空间距离建模进去后两者的直接路径系数掉到0.22且不再显著。真实的驱动机制是海拔梯度上的温度与湿度共变空间变量吸收了伪相关部分模型反而给出了更真实的效应。这个环节做不做直接决定你的SEM结论站不站得住。4.2 先诊断模型残差里到底有没有空间结构判断是否需要在SEM里处理空间自相关不能只看原始变量要看模型残差。流程是拟合完不含空间项的SEM提取每个观测的残差然后计算Morans I检验残差是否存在显著空间自相关。library(spdep) # 提取第一方程残差 res - residuals(fit, type raw)[, div] # 建立样方邻接矩阵或距离权重矩阵 coords - as.matrix(dat[, c(longitude, latitude)]) nb - knn2nb(knearneigh(coords, k 4)) lw - nb2listw(nb, style W) # Morans I检验 moran.test(res, lw, randomisation TRUE, alternative two.sided)如果Morans I显著P 0.05说明残差还有空间结构没有被模型解释这时候加入空间项是正当的并且要在论文里写明这一步。如果Morans I不显著那么恭喜你可以直接进入下一节。需要注意knn里k的选择会影响结果一般用4-8个最近邻我习惯做敏感性检查换几种k值看结论是否一致。还有一种更前置的方法在跑SEM之前先对每个变量做空间自相关检验确定哪些变量带明显空间梯度。但变量有空间梯度不代表SEM残差有问题因为SEM里的协变量可能已经解释了空间结构。所以归根到底还是看残差。4.3 方案一MEM空间滤波器lavaan最顺手的空间解法将空间特征向量作为协变量放进SEM是最容易实现、也最容易被审稿人接受的方法。核心是用空间距离矩阵生成一组正交的空间特征向量MEM变量这些向量代表不同尺度的空间结构然后筛选出与响应变量显著相关的少量向量放进lavaan模型作为额外的解释变量。library(adespatial) # 生成空间特征向量 mem - dbmem(coords, thresh NULL) # mem是包含多列空间向量的矩阵每一列对应一个空间尺度 # 筛选显著特征向量先把候选MEM和模型剩余残差做回归 r - residuals(fit, type raw)[, div] candidates - as.data.frame(mem) probe - apply(candidates, 2, function(v) { m - lm(r ~ v) summary(m)$coefficients[2, 4] }) keep - names(which(probe 0.05)) dat_sp - cbind(dat, candidates[, keep]) # 将这些MEM变量作为外生变量加入模型 mem_formula - paste(keep, collapse ) model_sp - paste0(div ~ prod climate , mem_formula, prod ~ climate soil , mem_formula)MEM变量之间是正交的所以即使加入十几个也不会造成严重共线性但为了模型简洁我通常只保留显著的那几个。这个方法的优点非常突出它是基于数据驱动但又有明确生态解释的不同MEM向量代表不同空间尺度你可以在方法部分写we included significant Morans eigenvector maps as covariates to account for residual spatial autocorrelation。审稿人看到这句话基本就认可了。4.4 方案二地理距离或坐标直接入模型如果不喜欢黑箱式的MEM另一个直接的方案是把坐标项或地理距离本身放进模型。比如加入经纬度的一次项和二次项相当于把空间趋势面建模进去或者计算每个样方到某个中心点的距离dat$long2 - dat$longitude^2 dat$lat2 - dat$latitude^2 model_geo - div ~ prod climate longitude latitude long2 lat2 prod ~ climate soil 这个方法容易解释但拟合能力比特种MEM弱尤其是非线性空间结构如山脊线、河道格局很难用坐标多项式表达。我的使用原则是样本量小、空间尺度单一、趋势平缓时用坐标趋势面空间格局复杂时用MEM。两者也可以结合先放坐标多项式再看残差是否需要MEM。4.5 方案三两段式SEM先除去空间趋势再建模两段式做法是第一步对每个变量做空间回归比如用MEM或坐标基做GAM提取残差作为空间校正后的变量第二步用这些校正残差跑lavaan SEM。思路简单粗暴但有一个统计问题——校正后的残差已经丢失了变量间的空间共变信息如果你的研究问题本身就包含空间机制比如海拔梯度驱动温度进而影响多样性两段式会把机制偷走路径系数变得难以解释。所以我的建议是两段式SEM只适合处理那些纯粹由采样设计带来的空间伪重复不适合处理生态学机制中真实存在的空间梯度效应。如果你做的是宏生态学或大尺度生物地理学研究空间梯度本身就是核心变量之一老老实实把空间变量放进SEM里建模而不是把它们删干净。4.6 加入空间项后的模型解读边界空间项进入SEM后非空间路径的系数会发生变化——这可能让原有路径不再显著也可能暴露新的机制。论文里不要只说我们控制了空间自相关要给出空间变量的显著性、残差Morans I的变化值。比如加入MEM变量后残差Morans I从0.31降至-0.02P 0.48表明空间结构已被充分解释。这句话很加分因为它证明你理解了空间自相关的来源而不是单纯为了凑数加变量。5. 顶刊审稿人会怎么审你的SEM部分拟合指标与汇报细节5.1 不要只给路径图把拟合指标表放进去很多生态学论文里SEM结果就是一张路径图系数和显著性标在箭头上然后正文吹一波。但顶刊审稿人越来越熟悉SEM的用法会追问模型整体拟合程度。你现在正准备投稿至少要在附录或正文给出一张包含以下指标的表格指标生态学观测数据可接受阈值备注Chi-square p值0.05为佳但小样本常显著不要因为p值小就判死刑CFI0.900.95以上更好TLI0.90与CFI类似RMSEA0.080.06更佳小样本会偏高结合置信区间看SRMR0.08缺失值FIML下可能无法计算AIC用于模型比较不用绝对值做判断这里有一个特别容易踩的坑当样本量小于100时卡方检验基本都会拒绝模型CFI也会偏低。lavaan里可以用satorra.bentler或robust估计法如estimator MLR做稳健校正同时提高小样本下的表现。我一般的做法是estimator MLR跑一遍报告稳健版本的拟合指数审稿人不会挑刺。5.2 模型修正的边界修正指数是诱惑也是陷阱lavaan输出modification indices之后你会看到一长串如果添加这条路径卡方会下降多少。新手很容易顺着修正指数加路径直到模型拟合变得完美。但这样做有两点危险第一每一次模型修正都是数据驱动的探索如果修正没有先验理论支撑你在论文里很难解释为什么加这条路径第二修正指数推荐的都是残差协方差或跨方程路径经常在生态学里毫无机制意义比如把土壤氮直接连到鸟类多样性审稿人看到会直接开怼。我的原则是只有在修正指数建议的路径有明确生态学解释、且符合先验假设时才加并且要报告post-hoc modification was applied to add a path from X to Y based on a priori hypothesis of [机制]。加了之后还要检查是否大幅改变了已有路径系数如果改变太大那说明原来的模型识别有问题不要掩盖它要回到模型构建阶段。5.3 如何写方法部分给可复现的参数设置在论文方法部分我建议至少提供以下信息数据标准化方式比如continuous variables were z-scored before analysis、缺失值处理方式FIML或MI、估计法ML或MLR、拟合指标报告值、空间自相关处理方式MEM筛选过程和保留变量数、软件版本和包版本。标准句可以这样写We used structural equation modeling (SEM) to evaluate direct and indirect effects, implemented in R version 4.3.1 with the lavaan package (Rosseel, 2012). Continuous variables were z-transformed to obtain comparable standardized coefficients. Missing data were handled by full information maximum likelihood. The final model fit was assessed by chi-square test (χ² 12.34, df 9, P 0.19), CFI 0.98, RMSEA 0.03 (90% CI: 0.00–0.07), and SRMR 0.04. To account for residual spatial autocorrelation, we included Morans eigenvector maps selected at α 0.05, and residual Morans I was not significant after inclusion.这段直接用基本不会被挑战。lavaan文档里也要求引用Rosseel的文章别忘了。5.4 标准化系数和非标准化系数的汇报策略生态学论文里普遍喜欢标准化的路径系数因为可以直接比较效应大小比如土壤水分对多样性的标准化效应为0.42高于气候的0.25。lavaan输出std.all列就是完全标准化系数。但标准的估计和区间在非线性项上会变得不太好解释因为二次项的标准化系数不能按常规方式解读。我的习惯是对线性路径汇报标准化系数对非线性项单独用效应图展示不强行解释标准化二次项系数。6. 一个完整案例复盘从数据到模型再到论文方法段落6.1 案例背景与初始假设假设我们研究山地草甸植物多样性div与生产力prod的关系数据来自60个样方包含年均温temp、土壤全氮soilN两个环境变量所有变量都存在缺失缺失率约12%样方沿山坡呈空间分布明显存在海拔梯度。初始假设是气候和土壤通过生产力间接影响多样性同时气候直接作用于多样性而生产力与多样性之间存在非线性关系。第一步数据探索与预处理。dat - read.csv(meadow_data.csv) summary(dat) # 检查缺失 hist(dat$prod)变量里prod有明显右偏先做对数变换div是Shannon指数基本对称。所有连续变量标准化为z分数。用cor和散点图检查prod-div关系发现明显单峰趋势确定需要加入二次项。6.2 建模过程中的关键决策先在lavaan里跑线性基线模型发现CFI只有0.82RMSEA达到0.09明显不过关。加入prod二次项后CFI升到0.94RMSEA降到0.05anova检验显示非线性项显著。接着检查缺失值原始有效样本60个listwise删除后只剩48个改用missing ml后模型估计全部使用60样方。最后提取模型残差算Morans IP 0.003残差存在明显空间结构于是用dbmem生成MEM筛选出2个显著特征向量加入模型后再测残差Morans IP 0.31问题解决。# 完整模型 model_final - div ~ prod I(prod^2) temp soilN mem1 mem2 prod ~ temp soilN fit_final - sem(model_final, data dat, missing ml, estimator MLR) summary(fit_final, fit.measures TRUE, standardized TRUE, rsquare TRUE)最终拟合指标χ² 8.21, df 6, P 0.22CFI 0.99RMSEA 0.03SRMR 0.04。路径系数prod的一次项显著正β 0.38二次项显著负β -0.29说明单峰关系成立temp对div的标准化效应为0.18不显著但方向合理soilN对prod的效应为0.52显著。总效应分解后temp通过prod对div的间接效应为0.18×0.38≈0.068这个值很小说明气候的直接作用是主导。6.3 论文里的方法段落和结果汇报范本把上面这些写进论文方法部分可以这样组织先一句话说明使用SEM的原因再说数据预处理然后依次说变量变换、缺失值处理、非线性处理、空间自相关处理最后列出软件版本。结果部分放一张SEM路径图箭头上标注标准化系数和显著性星号图注里写样本量、拟合指标表里放所有变量均值、标准差、缺失率以及模型拟合指标列。补充材料里放线性模型的比较表、MEM筛选细节、残差Morans I检验结果以备审稿人质疑。我在实际投稿中的体会是做好非线性、缺失值、空间自相关这三件事SEM部分基本不会被要求大改。反而是那些只给路径图、不写拟合指标、不提缺失机制的文章容易被审稿人一句话打回请说明模型拟合程度及缺失数据处理方法。所以这一套东西不只是为了过审更是为了让你的结论经得起复现和推敲。最后分享一个小技巧每次跑完SEM把lavaan输出的fit.measures、参数估计表和残差都存成CSV归档连同R脚本一起放进论文的补充材料或GitHub仓库。一来是满足期刊数据可用性要求二来几个月后回复审稿人质疑时你还能精确想起当时用的是哪个种子、哪套MEM筛选阈值。这种细节关键时候能救你一命。
返回列表