R實戰 第十篇:列聯表和頻數表
列聯表是觀測資料按兩個或更多屬性(定性變數)分類時所列出的頻數分佈表,它是由兩個以上的變數進行交叉分類的頻數分佈表。互動分類的目的是將兩變數分組,然後比較各組的分佈狀況,以尋找變數間的關係。
按兩個變數交叉分類的,該列聯表稱為兩維列聯表;若按3個變數交叉分類,所得的列聯表稱為3維列聯表,依次類推。一維列聯表就是頻數分佈表。頻數就是各個分組中屬性出現的次數。
頻數也稱“次數”,對樣本資料按某些屬性進行分組,統計出各個組內含個體的個數,就是頻數。
本文使用vcd包中的Arthritis資料集來演示如何建立列聯表。
一,建立頻數表
頻數表用於探索類別型變數,常用table()和 xtabs()來建立頻數表:
table(var1, var2, ...,varN) xtabs(formula, data)
引數註釋:
- table()函式:使用N個類別變數(因子)建立一個N維列聯表,
- xtabs()函式:根據一個公式(~var1+var2+...+varN)建立一個N維列聯表。
總體來說,要進行交叉分類的變數應出現在公式的右側,即 ~ 符號的右方,以+ 作為分割符。本文重點介紹一維列聯表和二維列聯表,對於高維列聯表,不做介紹。
函式prop.table()以列聯表作為引數,以margins定義的邊際把列聯表中的頻數表示為比例關係。
prop.table(table,margins)
引數註釋:table是列聯表,margins是邊際列表,1是第一個分類變數,2是第二個分類變數
函式margin.table()以列聯表作為引數,以margins定義的邊際列表來計算頻數的和。
margin.table(table,margins)
引數註釋:table是列聯表,margins是邊際列表,1是第一個分類變數,2是第二個分類變數
1,建立一維列聯表
一維列聯表是根據一個分類變數列出變數各個值得頻數:
with(Arthritis,table(Improved)) xtabs(~Improved,data=Arthritis)
Improved是分類得變數名,None、Some和Marked是變數的值,數值是各個變數值出現的次數(頻數)。
Improved NoneSome Marked 421428
2,建立二維列聯表
二維列聯表是指按照兩個分類變數列出的頻數表:
with(Arthritis,table(Improved,Sex)) xtabs(~Improved+Sex,data=Arthritis)
Sex和Improved是分類的變數名,兩個分類交叉分類,檢視兩個分類之間的關係:
Sex Improved Female Male None2517 Some122 Marked226
3,把列聯表的頻數轉換為比例值
使用prop.table(),把列聯表的頻數轉換為比例值
mytable <- xtabs(~Improved+Sex,data=Arthritis) prop.table(mytable) Sex ImprovedFemaleMale None0.29761905 0.20238095 Some0.14285714 0.02380952 Marked 0.26190476 0.07142857
4,計算列聯表的邊際列表的和
使用margin.table(),按照邊際列表計算列聯表的頻數之和
mytable <- xtabs(~Improved+Sex,data=Arthritis) margin.table(mytable,1) Improved NoneSome Marked 421428
二,自定義區間
按照分類變數來計算頻數,有時不能滿足需要,例如,按照年齡段來計算頻數,每10年為一個年紀段,統計各個年齡段的人數。由於Arthritis資料集中並沒有該分類變數,這就需要自定義區間,按照分組的間隔來製作頻數分佈表。
我從網上找到一個製作頻率分佈表的步驟,總共4步。
製作頻率分佈表的步驟如下:
1.求全距(全距亦稱極差):從資料中找出最大值Max和最小值Min,並求出它們的差,本例中最大值Max=100,最小值Min=42,故全距為Max-Min=100-42=58,從全距可以初步瞭解資料的差異幅度,同時亦為決定組距與組數提供了依據。
2.決定組距與組數:組數D和組距K之間有關係式D>=(Max- Min)/K,本例中取K=5,則D= (Max-Min)/K=58/5,向上取整為12,故分為12組。
3.決定組限:組限就是表明每組兩端的數值,其中每組的起點數值稱為下限 RL ,終點數值稱為上限 RU ,上限和下限也是資料的分點,通常區間是左閉右開型的:[ RL , RU )
4.製作頻率分佈表:其中落在各個小組內的資料個數即為頻數(或稱次數),常用f表示,每一小組的頻數與樣本容量的比值即為頻率。
step1,求極差
最大值是74,最小值是23,極差是51
age_range <- max(Arthritis$Age)-min(Arthritis$Age)
step2,決定組距和組數
把組距定為10,那麼組數是6(不小於 51/10 的最小整數)
step3,決定分點
使用cut()函式來分割Age資料,設定斷點向量breaks,以及每個區間的名稱lables:
labels <- c("< 30", "30 - 40", "40 - 50", "50 - 60", "60 - 70", ">= 70") breaks <- c(1,30,40,50,60,70,100)
step4,製作頻數分佈表
使用cut()函式按照指定的斷點來分割資料,得到各個分組,使用table()函式得到頻數表:
mytable <- cut(Arthritis$Age, breaks = breaks, labels = labels, right = TRUE ) df <- as.data.frame(table(Age=mytable)) #names(df)[1] <- c('Age')
cut()函式返回的是mytable的型別是因子,也就是說,cut()函式返回的結果是因子向量:
class(mytable) [1] "factor"
檢視頻數分佈表,按照Age(把mytable重新命名為Age)因子進行分組,統計各個因子屬性值的頻數:
> table(Age=mytable) Age < 30 30 - 40 40 - 50 50 - 60 60 - 70>= 70 781229271
把頻數分佈錶轉換為資料框,得到二維表如下圖所示:
> df Age Freq 1< 307 2 30 - 408 3 40 - 5012 4 50 - 6029 5 60 - 7027 6>= 701
step5,列出頻率分佈表
列出頻率分佈表,包括累積頻數和累計頻率
df <- transform(df, cumFreq = cumsum(Freq), FreqRate = prop.table(Freq)) df <- transform(df, cumFreqRate= cumsum(FreqRate)) df <- transform(df,FreqRate=round(FreqRate * 100,2), cumFreqRate= round(cumFreqRate*100,2))
檢視頻率分佈表:
Age Freq cumFreq FreqRate cumFreqRate 1< 30778.338.33 2 30 - 408159.5217.86 3 40 - 50122714.2932.14 4 50 - 60295634.5266.67 5 60 - 70278332.1498.81 6>= 701841.19100.00
參考文件: