R中的列联表使用教程

首先, 让我们获取一些数据。 MASS软件包包含1993年在美国销售的93辆汽车的数据。这些数据存储在Cars93对象中, 并且每辆汽车包含27个特征, 其中一些是分类的。因此, 让我们加载MASS软件包, 并查看cars93中包含的车辆类型:

library(MASS) Cars93$Type##[1] SmallMidsize Compact Midsize Midsize Midsize LargeLarge ##[9] Midsize LargeMidsize Compact Compact SportyMidsize Van ## [17] VanLargeSportyLargeCompact LargeSmallSmall ## [25] Compact VanMidsize SportySmallLargeSmallSmall ## [33] Compact SportySportyVanMidsize LargeSmallSporty ## [41] SportySmallCompact SmallSmallSportyMidsize Midsize ## [49] Midsize Midsize Midsize LargeSmallSmallCompact Van ## [57] SportyCompact Midsize SportyMidsize SmallMidsize Small ## [65] Compact VanMidsize Compact Midsize VanLargeSporty ## [73] SmallCompact SportyMidsize LargeCompact SmallSmall ## [81] SmallCompact SmallSmallSportyMidsize VanSmall ## [89] VanCompact SportyCompact Midsize ## Levels: Compact Large Midsize Small Sporty Van

那里有6种类型的汽车。 table函数告诉我们每种类型有多少种:
table(Cars93$Type)## ## CompactLarge MidsizeSmallSportyVan ##16112221149

prop.table将其转换为分数:
prop.table(table(Cars93$Type))## ##CompactLargeMidsizeSmallSportyVan ## 0.17204301 0.11827957 0.23655914 0.22580645 0.15053763 0.09677419

与汽车的起源相同:
table(Cars93$Origin)## ##USA non-USA ##4845prop.table(table(Cars93$Origin))## ##USAnon-USA ## 0.516129 0.483871

太好了, 我们发现我们的数据集包含相似数量的美国和非美国汽车, 并且最普遍的类型是中型和小型。但是, 也许美国和非美国在类型上有所不同?
让我们来看看汽车的种类和来源。我们可以再次使用table, 但是现在有两个参数。第一个将成为行变量, 第二个将成为列变量:
table(Cars93$Type, Cars93$Origin)## ##USA non-USA ##Compact79 ##Large110 ##Midsize1012 ##Small714 ##Sporty86 ##Van54

现在, 我们看到了每个人都知道的:美国人喜欢大型车辆!上表显示了两个类别变量(类型和来源)的联合分布。这样的表称为列联表。
rowSums和colSums函数确实是不言自明的
(tab1< -table(Cars93$Type, Cars93$Origin))## ##USA non-USA ##Compact79 ##Large110 ##Midsize1012 ##Small714 ##Sporty86 ##Van54rowSums(tab1)## CompactLarge MidsizeSmallSportyVan ##16112221149colSums(tab1)##USA non-USA ##4845

与表格嵌套的prop.table给出频率
prop.table(table(Cars93$Type, Cars93$Origin))## ##USAnon-USA ##Compact 0.07526882 0.09677419 ##Large0.11827957 0.00000000 ##Midsize 0.10752688 0.12903226 ##Small0.07526882 0.15053763 ##Sporty0.08602151 0.06451613 ##Van0.05376344 0.04301075

转换为百分数只是乘以100:
prop.table(table(Cars93$Type, Cars93$Origin))*100## ##USAnon-USA ##Compact7.5268829.677419 ##Large11.8279570.000000 ##Midsize 10.752688 12.903226 ##Small7.526882 15.053763 ##Sporty8.6021516.451613 ##Van5.3763444.301075

注意, 这是一个联合概率分布, 从中我们可以看到, 例如, 约有7.5%的汽车是小型汽车, 并且是美国原产的。
通常, 我们对一个变量在另一个变量创建的组中的分布感兴趣。在这里, 美国和(分别)非美国汽车之间的汽车类型分布似乎很有趣。为此, 我们使用prop.table函数的margin参数。它告诉分组变量在行(margin = 1)或列(margin = 2)中的哪个位置:
prop.table(table(Cars93$Type, Cars93$Origin), margin=2)*100## ##USAnon-USA ##Compact 14.583333 20.000000 ##Large22.9166670.000000 ##Midsize 20.833333 26.666667 ##Small14.583333 31.111111 ##Sporty16.666667 13.333333 ##Van10.4166678.888889

现在, 我们可以轻松地看到, 在美国以外的地区, 小型汽车的使用频率是数据集中美国部分地区的两倍。
还要注意, 百分比在列中总计为100, 而在联合分配表(不带边距参数的百分比)中, 100是整个表的总和。
(tab2< -prop.table(table(Cars93$Type, Cars93$Origin), margin=2)*100)## ##USAnon-USA ##Compact 14.583333 20.000000 ##Large22.9166670.000000 ##Midsize 20.833333 26.666667 ##Small14.583333 31.111111 ##Sporty16.666667 13.333333 ##Van10.4166678.888889colSums(tab2)##USA non-USA ##100100

列联表中最常见的问题是行和列变量是否独立。回答这个问题的最基本方法是运行卡方检验。本教程将对此进行详细介绍。让我们检查Type和Origin是否独立:
chisq.test(Cars93$Type, Cars93$Origin)## Warning in chisq.test(Cars93$Type, Cars93$Origin): Chi-squared ## approximation may be incorrect## ##Pearson's Chi-squared test ## ## data:Cars93$Type and Cars93$Origin ## X-squared = 14.08, df = 5, p-value = http://www.srcmini.com/0.01511

显然, 它们不是, 但是我们也得到了卡方近似值可能是错误的警告。这是因为卡方统计量仅近似遵循卡方分布。我们拥有的观察越多, 近似值就越好。每当预期计数之一小于5时, chisq.test函数就会引发上述警告(有关” 预期计数” 的信息, 请参见上面链接的教程)。
Fisher精确检验是卡方检验的替代方法, 主要在卡方逼近不令人满意时使用。让我们运行它:
fisher.test(Cars93$Type, Cars93$Origin)## ##Fisher's Exact Test for Count Data ## ## data:Cars93$Type and Cars93$Origin ## p-value = http://www.srcmini.com/0.007248 ## alternative hypothesis: two.sided

结果与卡方的结果非常相似, 但并非总是如此。 Fisher精确测试的一个主要缺点是, 对于大表(或大样本), 它在计算上变得无效。
另一种选择是所谓的G检验。它的统计量也近似为卡方分布, 但对于小样本, 此近似值比卡方检验所使用的近似值更近。对于G测试, 我们可以使用DescTools包中的GTest函数。结果再次与之前的两个测试非常相似:类型和来源不是独立的。
library(DescTools) GTest(Cars93$Type, Cars93$Origin)## ##Log likelihood ratio (G-test) test of independence without ##correction ## ## data:Cars93$Type and Cars93$Origin ## G = 18.362, X-squared df = 5, p-value = http://www.srcmini.com/0.002526

在2× 2列联表中, 可以通过Yates的连续性校正来增强卡方检验。它简单地从每个|减去0.5。观察-预期|卡方统计中的术语。如果你现在迷路了, 请再次参考本教程。而且, R会在必要时自动应用Yates校正。让我们看看美国和非美国汽车的手动变速箱版本的可用性:
(tab3< -table(Cars93$Man.trans.avail, Cars93$Origin))## ##USA non-USA ##No266 ##Yes2239chisq.test(tab3)## ##Pearson's Chi-squared test with Yates' continuity correction ## ## data:tab3 ## X-squared = 15.397, df = 1, p-value = http://www.srcmini.com/8.712e-05

耶茨的校正是自动应用的, R告诉了我们。
让我们一次查看Man.trans.avail, Origin和Type。表根据提供的第三变量对数据集进行拆分:
table(Cars93$Man.trans.avail, Cars93$Origin, Cars93$Type)## , , = Compact ## ## ##USA non-USA ##No20 ##Yes59 ## ## , , = Large ## ## ##USA non-USA ##No110 ##Yes00 ## ## , , = Midsize ## ## ##USA non-USA ##No94 ##Yes18 ## ## , , = Small ## ## ##USA non-USA ##No00 ##Yes714 ## ## , , = Sporty ## ## ##USA non-USA ##No00 ##Yes86 ## ## , , = Van ## ## ##USA non-USA ##No42 ##Yes12

ftable提供了更紧凑的视图:
ftable(Cars93$Man.trans.avail, Cars93$Origin, Cars93$Type)##Compact Large Midsize Small Sporty Van ## ## NoUSA2119004 ##non-USA004002 ## Yes USA501781 ##non-USA9081462

从上面的表结果中, 应该清楚Origin和Man.trans.avail之间的关系随类型而不同。例如, 对于小型和运动型汽车, 没有关联:每辆美国以及每辆非美国的小型或运动型汽车都带有手动版本。另一方面, 大多数中型美国汽车没有手动版本, 而大多数此类非美国汽车却没有。为了说明层中可能存在的不同关系, 可以使用Cochran-Mantel-Haenszel检验:
mantelhaen.test(Cars93$Man.trans.avail, Cars93$Origin, Cars93$Type)## ##Mantel-Haenszel chi-squared test with continuity correction ## ## data:Cars93$Man.trans.avail and Cars93$Origin and Cars93$Type ## Mantel-Haenszel X-squared = 8.0153, df = 1, p-value = http://www.srcmini.com/0.004638 ## alternative hypothesis: true common odds ratio is not equal to 1 ## 95 percent confidence interval: ##2.226531 76.891307 ## sample estimates: ## common odds ratio ##13.08438

传递给mantelhaen.test的第三个参数标识层。将以上结果与没有分层的结果进行比较(上面的Yates校正示例)。协会仍然存在, 但是证据却很薄弱。
一旦我们发现了变量之间的一些关联, 就该测量它们的强度了。有多种类型的可能的措施。其中有许多描述。现在, 我将重点介绍两种使用最广泛的方法。
V基于卡方统计量:
$$ V = \ sqrt {\ frac {\ chi ^ 2 / N} {\ min(C-1, R-1)}}, $$其中:
  • N是列联表(所有单元格的总和)的总计,
  • C是列数
  • R是行数。
V∈[0; 1]。 V越大, 变量之间的关系越强。 V = 0可以解释为独立性(因为且仅当χ2= 0时, V = 0)。 V的主要缺点是缺乏精确的解释。 V = 0.6是强, 中还是弱关联?
DescTools的CramerV函数可以为我们计算出它:
CramerV(Cars93$Type, Cars93$Origin)## [1] 0.3890967

再一次:这是强, 中还是弱的联系?
古德曼(Goodman)和克鲁斯卡尔(Kruskal)拉姆达(lambda)是基于变化成比例减少的度量的一个示例。这些措施旨在模仿R2-线性回归的确定系数:
  • 他们从[0, 1]取值
  • 它们表示由独立变量解释的一部分变化。
让我们使用列变量作为独立变量。然后, 古德曼和克鲁斯卡尔的lambda公式为:$$ \ lambda = \ frac {L-\ sum_j L_j} {L}, $$其中:
  • Lj是第j列中的非模态频率之和,
  • L是” 总计” 列中非模态频率的总和
最好用一个例子来解释。让我们看一下Type和Origin, 后者是独立的:
table(Cars93$Type, Cars93$Origin)## ##USA non-USA ##Compact79 ##Large110 ##Midsize1012 ##Small714 ##Sporty86 ##Van54

US列的模式为11, 因此L1 = 7 + 10 + 7 + 8 + 5 = 37;非US列的模式为14, 因此L2 = 9 + 0 + 12 + 6 + 4 = 31。是
rowSums(table(Cars93$Type, Cars93$Origin))## CompactLarge MidsizeSmallSportyVan ##16112221149

模式为22, 因此L = 16 + 11 + 21 + 14 + 9 = 71和$$ \ lambda = \ frac {71-(37 + 31)} {71} = 0.042 $$
我们可以改用DescTools包中的Lambda函数:
Lambda(Cars93$Type, Cars93$Origin, direction='row')## [1] 0.04225352

direction参数确定因变量在行中或列中的位置。
来源仅解释类型变化的4%。从公式中注意到, lambda将变异定义为属于最大群与不属于最大群之间的二分法。
值得一提的是, 每列的模态类别相同时, lambda为零。看看这张桌子:
(lambdaTab< -cbind(c(0, 100), c(49, 51)))##[, 1] [, 2] ## [1, ]049 ## [2, ]10051chisq.test(lambdaTab)## ##Pearson's Chi-squared test with Yates' continuity correction ## ## data:lambdaTab ## X-squared = 62.279, df = 1, p-value = http://www.srcmini.com/2.981e-15

模态类别对于每一列都是相同的(第二行)。因此, 尽管存在显着可见的关联, 但lambda必须为零:
Lambda(lambdaTab, direction='row')## [1] 0

【R中的列联表使用教程】如果你想了解有关R中统计信息的更多信息, 请参加srcmini的R中统计模型(第1部分)课程。

    推荐阅读