Main Content

本页的翻译已过时。点击此处可查看最新英文版本。

splitapply

将数据划分归组并应用函数

说明

示例

Y = splitapply(func,X,G)X 划分为 G 指定的组,并向每个组应用函数 funcsplitapply 以数组形式返回 Y,其中包含对从 X 划分出的组应用 func 后的串联输出。输入参数 G 是由正整数组成的向量,用于指定 X 的对应元素属于哪个组。如果 G 包含 NaN 值,则 splitapply 在将 X 划分归组时会省略 X 中的对应值。要创建 G,您可以使用 findgroups 函数。

splitapply拆分-应用-合并工作流中的两个步骤进行了合并。

示例

Y = splitapply(func,X1,...,XN,G)X1,...,XN 划分归组并应用 funcsplitapply 函数对每个组调用一次 func,同时将来自 X1,...,XN 的对应元素作为 funcN 个输入参数。

示例

Y = splitapply(func,T,G) 将表 T 的变量划分归组并应用 funcsplitapply 函数将 T 的变量视为向量、矩阵或元胞数组,具体取决于表变量的数据类型。如果 TN 个变量,则 func 必须接受 N 个输入参数。

示例

[Y1,...,YM] = splitapply(___) 将变量划分归组并向每个组应用 funcfunc 返回多个输出参数。Y1,...,YM 包含对从输入数据变量划分出的组应用 func 后的串联输出。func 可以返回属于不同类的输出参数,但在每次调用 func 时每个输出的类必须是相同的。您可以将此语法与前面语法中的任何输入参数结合使用。

func 返回的输出参数的数量不必与 X1,...,XN 指定的输入参数的数量相同。

示例

全部折叠

计算各患者组按性别的平均高度,并显示结果。

从数据文件 patients.mat 加载患者的身高和性别数据。

load patients
whos Gender Height
  Name          Size            Bytes  Class     Attributes

  Gender      100x1             11412  cell                
  Height      100x1               800  double              

使用 findgroups 按性别分组。

G = findgroups(Gender);

Height 划分为由 G 指定的组。按性别计算平均高度。输出参数的第一行是女性患者的平均身高,第二行是男性患者的平均身高。

splitapply(@mean,Height,G)
ans = 2×1

   65.1509
   69.2340

计算各患者组的血压读数差异的方差,并显示结果。血压读数包含在两个数据变量中。要计算差异,请使用带有两个输入参数的函数。

从数据文件 patients.mat 加载 100 位患者的血压读数和吸烟数据。

load patients
whos Systolic Diastolic Smoker
  Name             Size            Bytes  Class      Attributes

  Diastolic      100x1               800  double               
  Smoker         100x1               100  logical              
  Systolic       100x1               800  double               

func 定义为一个函数,用于计算烟民和非烟民的收缩压和舒张压血压读数之间差异的方差。func 要求两个输入参数。

func = @(x,y) var(x-y);

使用 findgroupssplitapply 将患者数据划分归组并计算差异的方差。findgroups 还会返回 smokers 中的组标识符。splitapply 函数对每个组调用一次 func,且使用 SystolicDiastolic 作为两个输入参数。

[G,smokers] = findgroups(Smoker);
varBP = splitapply(func,Systolic,Diastolic,G)
varBP = 2×1

   44.4459
   48.6783

创建一个表,其中包含差异的方差以及每个组中的患者人数。

numPatients = splitapply(@numel,Smoker,G);
T = table(smokers,numPatients,varBP)
T=2×3 table
    smokers    numPatients    varBP 
    _______    ___________    ______

     false         66         44.446
     true          34         48.678

计算各患者组的最小、中位数和最大体重,并以数组形式返回每个组的这些结果。splitapply 会串联各输出参数,以便您能够区分各个组的输出。

定义一个函数,它以行向量形式返回最小值、中位数和最大值。

mystats = @(x)[min(x) median(x) max(x)];

patients.mat 加载烟民患者的体重、性别和状态信息。

load patients
whos Weight Gender Smoker
  Name          Size            Bytes  Class      Attributes

  Gender      100x1             11412  cell                 
  Smoker      100x1               100  logical              
  Weight      100x1               800  double               

使用 findgroupssplitapply 将患者体重划分归组并计算每个组的统计量。

G = findgroups(Gender,Smoker);
Y = splitapply(mystats,Weight,G)
Y = 4×3

  111.0000  131.0000  147.0000
  115.0000  131.0000  146.0000
  158.0000  181.5000  194.0000
  164.0000  181.0000  202.0000

在此示例中,您可以行向量形式返回非标量输出,因为数据和分组变量是列向量。Y 的每一行包含一个不同患者组的统计量。

根据患者数据表计算中位身体-质量-索引 (BMI)。按性别和状态(烟民或非烟民)对患者分组。

将患者数据和分组变量加载到表中。

load patients
DT = table(Height,Weight);
GT = table(Gender,Smoker);

定义一个函数,以根据组别或患者的体重和身高计算中位 BMI。

meanBMIFcn = @(h,w)mean((w ./ (h.^2)) * 703);

创建一个表,其中包含每个组的中位 BMI。

[G,results] = findgroups(GT);
meanBMI = splitapply(meanBMIFcn,DT,G);
results.meanBMI = meanBMI
results=4×3 table
      Gender      Smoker    meanBMI
    __________    ______    _______

    {'Female'}    false     21.672 
    {'Female'}    true      21.669 
    {'Male'  }    false     26.578 
    {'Male'  }    true      26.458 

计算患者组的最小、中位和最大身高,并在表中返回结果。

在名为 multiStats.m 的文件中定义一个函数,以接受输入向量并返回该向量的最小值、中值和最大值。

% Copyright 2015 The MathWorks, Inc.

function [lo,avg,hi] = multiStats(x)
lo = min(x);
avg = mean(x);
hi = max(x);
end

将患者数据加载到一个表中。

load patients
T = table(Gender,Height);
summary(T)
Variables:

    Gender: 100x1 cell array of character vectors

    Height: 100x1 double

        Values:

            Min          60   
            Median       67   
            Max          72   

按性别对患者身高进行分组。创建一个表,其中包含来自每个组的 multiStats 的输出。

[G,gender] = findgroups(T.Gender);
[minHeight,meanHeight,maxHeight] = splitapply(@multiStats,T.Height,G);
result = table(gender,minHeight,meanHeight,maxHeight)
result =

  2x4 table

      gender      minHeight    meanHeight    maxHeight
    __________    _________    __________    _________

    {'Female'}       60          65.151         70    
    {'Male'  }       66          69.234         72    

输入参数

全部折叠

要对数据组应用的函数,指定为函数句柄。

如果 func 返回非标量输出参数,则参数必须是定向的,以便 splitapply 可以将连续调用 func 所返回的输出参数串联起来。例如,如果输入数据变量为列向量,则 func 必须返回一个标量或行向量作为输出参数。

示例: Y = splitapply(@sum,X,G) 返回 X 中各数据组的总和。

数据变量,指定为向量、矩阵或元胞数组。X 的元素属于由 G 的对应元素指定的组。

如果 X 为矩阵,则 splitapply 将每个列或行视为单独的数据变量。G 的方向确定 splitapply 是将 X 的行还是列视为数据变量。

组编号,指定为由正整数组成的向量。

  • 如果 X 为向量或元胞数组,则 G 的长度必须与 X 相同。

  • 如果 X 为矩阵,则 G 的长度必须等于 X 的行数或列数,具体取决于 G 的方向。

  • 如果输入参数是表 T,则 G 必须为列向量。G 的长度必须等于 T 的行数。

数据变量,指定为表。splitapply 将每个表变量视为一个单独的数据变量。

详细信息

全部折叠

拆分-应用-合并工作流

拆分-应用-合并工作流在数据分析中很常见。在此工作流中,分析过程首先将数据分组,再对每个组应用一个函数,然后合并结果。下图显示了该工作流的典型示例以及由 findgroupssplitapply 实现的工作流部分。

扩展功能

在 R2015b 中推出