Main Content

table 内のデータでの計算

この例では、table 内のデータで計算を行う方法を示します。table には数値データと非数値データの両方を含めることができます。数値データを含む table 変数を特定したら、中かっこまたはドット表記を使用してこれらの変数内のデータにアクセスできます。その後、数値データに対して算術演算を実行したり関数を呼び出したりして、結果を table に代入し直すことができ、そのすべてを 1 行のコードで実行できます。また、関数 rowfun を使用して table の各行で計算を行うことや、関数 varfun を使用して変数に沿って計算を行うこともできます。table 内にデータ グループがある場合は、関数 groupsummaryrowfun、および varfun を使用して、table 内のグループごとに計算を実行できます。

table へのサンプル データの読み込み

関数 readtable を使用して、CSV (コンマ区切り値) ファイル testScores.csv から table へデータを読み取ります。このサンプル ファイルには、2 つの異なる学校に通う生徒 10 人のテストの得点が含まれています。出力 table には、数値データをもつ変数とテキスト データをもつ他の変数が含まれます。これらの変数の 1 つ School は、固定されたセットの値、つまりカテゴリをもっています。これらのカテゴリは、この table 内の 2 つの生徒グループを表します。Schoolcategorical 変数に変換します。

scores = readtable("testScores.csv","TextType","string");
scores.School = categorical(scores.School)
scores=10×5 table
     LastName       School      Test1    Test2    Test3
    __________    __________    _____    _____    _____

    "Jeong"       XYZ School     90       87       93  
    "Collins"     XYZ School     87       85       83  
    "Torres"      XYZ School     86       85       88  
    "Phillips"    ABC School     75       80       72  
    "Ling"        ABC School     89       86       87  
    "Ramirez"     ABC School     96       92       98  
    "Lee"         XYZ School     78       75       77  
    "Walker"      ABC School     91       94       92  
    "Garcia"      ABC School     86       83       85  
    "Chang"       XYZ School     79       76       82  

数値データをもつサブテーブルの作成

数値データのみをもつサブテーブルを作成します。最初の 2 つの変数は非数値データをもつため、簡単な方法の 1 つとして、table にその他の変数を指定するインデックスを付けることが挙げられます。

numericScores = scores(:,3:end)
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

     90       87       93  
     87       85       83  
     86       85       88  
     75       80       72  
     89       86       87  
     96       92       98  
     78       75       77  
     91       94       92  
     86       83       85  
     79       76       82  

あるいは、関数 vartype を使用して変数をデータ型で指定できます。この関数は、データ型が異なる多くの変数を含む大きな table がある場合に役立ちます。これにより、table 変数の指定に使用できる添字が返されます。

numericVars = vartype("numeric")
numericVars = 
	table vartype subscript:

		Select table variables matching the type 'numeric'

	See Access Data in a Table.

numericScores = scores(:,numericVars)
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

     90       87       93  
     87       85       83  
     86       85       88  
     75       80       72  
     89       86       87  
     96       92       98  
     78       75       77  
     91       94       92  
     86       83       85  
     79       76       82  

table データに対する算術の実行と関数の呼び出し

テストの得点は 100 点満点制です。別の点数制の得点に変換するには、得点に同じ係数を乗算します。

ただし、数値配列に使用する構文と同じものは使用できません。代わりに、データを配列に抽出してスケーリングし、table に代入し直します。このようにして、table の内容に対して 1 行のコードで算術演算を実行したり関数を呼び出したりできます。

table の "内容" を抽出するには、中かっこを使用します。たとえば、次の構文は numericScores のすべての行とすべての table 変数を指定し、結果を数値行列として返します。table 変数のデータ型に互換性がある限り、この方法でそれらの内容を連結できます。

A = numericScores{:,:}
A = 10×3

    90    87    93
    87    85    83
    86    85    88
    75    80    72
    89    86    87
    96    92    98
    78    75    77
    91    94    92
    86    83    85
    79    76    82

行列のサイズが table と同じでデータ型に互換性がある場合は、その行列を table の内容に代入できます。

テストの得点が 25 点満点制になるように数値データをスケーリングし、table に代入し直します。

numericScores{:,:} = numericScores{:,:} * 0.25
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

     22.5    21.75    23.25
    21.75    21.25    20.75
     21.5    21.25       22
    18.75       20       18
    22.25     21.5    21.75
       24       23     24.5
     19.5    18.75    19.25
    22.75     23.5       23
     21.5    20.75    21.25
    19.75       19     20.5

中かっこの代わりに、"T.Variables" を使用してすべての table 変数を指定できます。"T.Variables""T{:,:}" 構文と同じ内容を表します。

たとえば、各 table 変数内の最小値をその変数から減算します。

numericScores.Variables = numericScores.Variables - min(numericScores.Variables)
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

    3.75        3     5.25 
       3      2.5     2.75 
    2.75      2.5        4 
       0     1.25        0 
     3.5     2.75     3.75 
    5.25     4.25      6.5 
    0.75        0     1.25 
       4     4.75        5 
    2.75        2     3.25 
       1     0.25      2.5 

ドット表記と変数名を使用して、一度に 1 つの変数に対して計算を実行できます。たとえば、Test3 の最後の得点セットに補正相当の 5 点を追加します。その他の table 変数はこの演算の影響を受けません。

numericScores.Test3 = numericScores.Test3 + 5
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

    3.75        3     10.25
       3      2.5      7.75
    2.75      2.5         9
       0     1.25         5
     3.5     2.75      8.75
    5.25     4.25      11.5
    0.75        0      6.25
       4     4.75        10
    2.75        2      8.25
       1     0.25       7.5

table の各行の計算

生徒ごとにテストの得点の平均値、最小値、および最大値を求めます。これらの値は各行で計算します。それらを元の table に新しい table 変数として代入します。

簡単で便利な方法の 1 つとして、データを行列に抽出し、それに対して関数を呼び出してから、出力を新しい table 変数に代入することが挙げられます。たとえば、各行でテストの平均点を計算します。次に、それらを scores の新しい table 変数 TestMean に追加します。中かっこを使用して Test1Test2、および Test3 の数値データを行列に抽出します。各行の平均値を計算するには、mean を呼び出す際に次元を 2 と指定します。

vars = ["Test1","Test2","Test3"];
scores.TestMean = mean(scores{:,vars},2)
scores=10×6 table
     LastName       School      Test1    Test2    Test3    TestMean
    __________    __________    _____    _____    _____    ________

    "Jeong"       XYZ School     90       87       93           90 
    "Collins"     XYZ School     87       85       83           85 
    "Torres"      XYZ School     86       85       88       86.333 
    "Phillips"    ABC School     75       80       72       75.667 
    "Ling"        ABC School     89       86       87       87.333 
    "Ramirez"     ABC School     96       92       98       95.333 
    "Lee"         XYZ School     78       75       77       76.667 
    "Walker"      ABC School     91       94       92       92.333 
    "Garcia"      ABC School     86       83       85       84.667 
    "Chang"       XYZ School     79       76       82           79 

各行で計算を実行する別の方法としては、関数 rowfun を使用する方法があります。rowfun を使用する場合は、table からデータを抽出する必要はありません。代わりに、rowfun への入力引数として、table とデータに適用する関数を渡します。構文が少し複雑になりますが、rowfun は、適用する関数が複数の入力引数を取る場合や複数の出力引数を返す場合に役立ちます。

たとえば、関数 bounds を使用して、テストの最低点と最高点を求めます。関数 bounds は 2 つの出力引数を返すため、rowfun を使用してそれを scores に適用します。rowfun の出力は、変数 TestMin と変数 TestMax をもつ新しい table です。この場合、さらに "SeparateInputs"false と指定して、各行の値が bounds に渡される前にベクトルに結合されるようにします。

minmaxTest = rowfun(@bounds, ...
                    scores, ...
                    "InputVariables",vars, ...
                    "OutputVariableNames",["TestMin","TestMax"], ...
                    "SeparateInputs",false)
minmaxTest=10×2 table
    TestMin    TestMax
    _______    _______

      87         93   
      83         87   
      85         88   
      72         80   
      86         89   
      92         98   
      75         78   
      91         94   
      83         86   
      76         82   

scoresminmaxTest を連結して、これらの値が 1 つの table に含まれるようにします。

scores = [scores minmaxTest]
scores=10×8 table
     LastName       School      Test1    Test2    Test3    TestMean    TestMin    TestMax
    __________    __________    _____    _____    _____    ________    _______    _______

    "Jeong"       XYZ School     90       87       93           90       87         93   
    "Collins"     XYZ School     87       85       83           85       83         87   
    "Torres"      XYZ School     86       85       88       86.333       85         88   
    "Phillips"    ABC School     75       80       72       75.667       72         80   
    "Ling"        ABC School     89       86       87       87.333       86         89   
    "Ramirez"     ABC School     96       92       98       95.333       92         98   
    "Lee"         XYZ School     78       75       77       76.667       75         78   
    "Walker"      ABC School     91       94       92       92.333       91         94   
    "Garcia"      ABC School     86       83       85       84.667       83         86   
    "Chang"       XYZ School     79       76       82           79       76         82   

各 table 変数に沿った計算

各テストの平均点を求めます。これらの値は table 変数に沿って計算します。

最も簡単な方法は、mean を使用する方法です。まず、中かっこを使用して Test1Test2、および Test3 の数値データを行列に抽出します。次に、mean を呼び出して行列の各列の平均値を計算します。出力は、各要素が table 変数の平均値である数値ベクトルです。

vars = ["Test1","Test2","Test3"];
meanOfEachTest = mean(scores{:,vars})
meanOfEachTest = 1×3

   85.7000   84.3000   85.7000

table 変数に沿って計算を実行する別の方法としては、関数 varfun を使用する方法があります。varfun を使用する場合は、table からデータを抽出する必要はありません。代わりに、varfun への入力引数として、table とデータに適用する関数を渡します。

varfun を使用して平均点を計算します。出力は、table 変数にわかりやすい名前が付けられた新しい table です。

meanOfEachTest = varfun(@mean, ...
                        scores, ...
                        "InputVariables",vars)
meanOfEachTest=1×3 table
    mean_Test1    mean_Test2    mean_Test3
    __________    __________    __________

       85.7          84.3          85.7   

table 内のデータ グループを使用した計算

table に 1 つ以上の "グループ化変数" がある場合は、table 内のデータ グループに対して計算を実行できます。グループ化変数の値を使用して、行が属するグループを指定できます。

たとえば、scores の変数 School の値は ABC SchoolXYZ School の 2 つです。これら 2 つの値を、scores のデータ グループを表すカテゴリと見なすことができます。この場合、学校別に計算を実行できます。

関数を適用してグループ化変数を使用するには、関数 varfun を使用します。mean などの関数を指定し、varfun を使用して、指定した各 table 変数にその関数を適用できます。グループ化変数も指定すると、varfun は各 table 変数内の各グループに関数を適用します。

各テストの平均点を学校別に計算します。

vars = ["Test1","Test2","Test3"];
meanScoresBySchool = varfun(@mean, ...
                            scores, ...
                            "InputVariables",vars, ...
                            "GroupingVariables","School")
meanScoresBySchool=2×5 table
      School      GroupCount    mean_Test1    mean_Test2    mean_Test3
    __________    __________    __________    __________    __________

    ABC School        5            87.4            87          86.8   
    XYZ School        5              84          81.6          84.6   

R2018a 以降、関数 groupsummary を使用し、各 table 変数内のデータ グループに対して計算を実行することもできます。

meanScoresBySchool = groupsummary(scores,"School","mean",vars)
meanScoresBySchool=2×5 table
      School      GroupCount    mean_Test1    mean_Test2    mean_Test3
    __________    __________    __________    __________    __________

    ABC School        5            87.4            87          86.8   
    XYZ School        5              84          81.6          84.6   

groupsummary の構文の方が少し簡単です。また、groupsummary を使用すると一度に複数のメソッドを指定できます。たとえば、各テストの最低点と最高点の両方を学校別に求めます。

minmaxBySchool = groupsummary(scores,"School",["min","max"],vars)
minmaxBySchool=2×8 table
      School      GroupCount    min_Test1    max_Test1    min_Test2    max_Test2    min_Test3    max_Test3
    __________    __________    _________    _________    _________    _________    _________    _________

    ABC School        5            75           96           80           94           72           98    
    XYZ School        5            78           90           75           87           77           93    

groupsummary の事前定義されたメソッドをすべて使用するには、メソッドとして "all" を指定します。テストの平均点に関するすべての統計を学校別に計算します。

allStatsBySchool = groupsummary(scores,"School","all","TestMean")
allStatsBySchool=2×13 table
      School      GroupCount    mean_TestMean    sum_TestMean    min_TestMean    max_TestMean    range_TestMean    median_TestMean    mode_TestMean    var_TestMean    std_TestMean    nummissing_TestMean    nnz_TestMean
    __________    __________    _____________    ____________    ____________    ____________    ______________    _______________    _____________    ____________    ____________    ___________________    ____________

    ABC School        5            87.067           435.33          75.667          95.333           19.667            87.333            75.667           57.967          7.6136                0                  5      
    XYZ School        5              83.4              417          76.667              90           13.333                85            76.667           29.856           5.464                0                  5      

ある table 変数内の特定の値を求めてから、別の table 変数内の対応する値を求めることが必要になる場合があります。このような場合は rowfun を使用します。

たとえば、各学校でテストの平均点が最も高かった生徒を見つけます。添付のサポート関数 findNameAtMax は、最高点とその得点を獲得した生徒の名前の両方を返します。rowfun を使用して、findNameAtMax を各生徒グループに適用します。findNameAtMax は複数の入力引数 (姓とテストの得点) を取り、複数の出力引数も返すため、関数 rowfun が適しています。

maxScoresBySchool = rowfun(@findNameAtMax, ...
                           scores, ...
                           "InputVariables",["LastName","TestMean"], ...
                           "GroupingVariables","School", ...
                           "OutputVariableNames",["max_TestMean","LastName"])
maxScoresBySchool=2×4 table
      School      GroupCount    max_TestMean    LastName 
    __________    __________    ____________    _________

    ABC School        5            95.333       "Ramirez"
    XYZ School        5                90       "Jeong"  

サポート関数

function [maxValue,lastName] = findNameAtMax(names,values)
    % Return maximum value and the last name 
    % from the row at which the maximum value occurred
    [maxValue,maxIndex] = max(values);
    lastName = names(maxIndex);
end

参考

| | | | |

関連するトピック