1. 程式人生 > >列聯表分析基於R語言

列聯表分析基於R語言

本文中的資料為去頭資料,是我聚類後的一部分,具體變數是我命名的,沒有具體意義,放在這裡僅供學習和交流,請不要傳播和用於其他用途。資料下載連結:資料雲盤連結

一、列聯表基本概念

列聯表本質上是對資料在一維或多維上的邊際分佈的概率描述。

如下表

列聯表按表中元素的內容可以分為頻數列聯表和頻率列聯表,下面會看到。同時根據稀疏陣與否可以分為非稀疏列聯表和稀疏列聯表。

在通常的資料處理實踐中我們常常有要求資料在列聯表的一個維度上顯示多個特徵,如下圖:

這裡基本概念有空了在寫,昨天傳了兩張圖存草稿了,今天全沒了,等哪天在寫理論部分吧

二、變數組合形式的二維列聯表

橫列我們所展示的就是兩個特徵:學歷+男女,縱列展示的是地區,碰到這種情況時展示一下三種方法:1.table/xtabs函式;2.運用excel資料透視表;3.reshape包

1)先介紹第一種方法,這種較為麻煩,可是延續了table函式自帶的性質,如prop.table,margin.table,卡方值等

由於table、xtabs沒有特徵組合之間的列聯表,因此需要我們自己設定變數名,我的方法是:利用類似hash編碼的方式將二維變為一維,要保證不重複。本例中四個變數都是1到2位數,所以我新增兩個特徵horizon=num*100+$cluster,longitude=pay*100+orient,這樣不重不漏,也好辨識。所以pay+orient~num+cluster就變成了horizon~longitude

程式碼如下:

cross=read.csv("cross.csv")
cross=cross1#這裡備份,以後cross變數會改變
cross$horizon=cross$num*100+cross$cluster
cross$longitude=cross$pay*100+cross$orient
poo=xtabs(~horizon+longitude,data=cross,drop.unused.levels=FALSE)
#這裡其實drop.unused.levels=FALSE不起作用,因為levels是horizon和longitude,沒有出現的組合還是沒有出現,後面會介紹

由於這裡有些根本就木有存在的特徵組合,如pay=19,orient=5的組合,但是資料並不能夠識別這些不存在的組合。最後我們得到的tale必定沒有19,15這一列,依次類推我們,對於大量特徵的稀疏陣我們必定會出現大量根本沒有出現的特徵組合,實際上出現的一般不會超過10%。但是有時候我們在進行報表或者描述性統計時又必須加上這樣顯得規整和好看(當然如果你僅僅是做探索性分析,這裡table全不全沒有關係,但是有的描述性分析就要這樣一張表,畢竟資料分析是後臺,往往是被要求的職位,各種各樣的資料要求都可能出現)

方法一,新增行和列的factor,對沒有出現的factor加入levels中去,由於沒出現的有十幾列,十幾行,需要匹配尋找漏的哪幾條,較為麻煩,不推薦。

方法二,構造一個新資料,在原資料的基礎上新增longtitude*honrizon個行,每行新增一條資料(由於是頻數統計,新增NA或0都可以),這樣xtabs就會有全部特徵組合的table了,而table減去一個全1矩陣(行和列元素全為1)就得到了應有的table

程式碼如下:

longitu=c();m=1
for(i in 1:length(unique(cross$num))){
	for(j in 1:length(unique(cross$cluster))){
	longitu[m]=100*i+j
	m=m+1
	next
	}
}
hori=c();m=1
for(i in 1:length(unique(cross$area))){
	for(j in 1:length(unique(cross$orient))){
	hori[m]=100*i+j
	m=m+1
	next
	}
}
m=length(cross$longitude)+1
for(i in 1:length(coo)){
	for(j in 1:length(doo)){
		cross[m,c("horizon","longitude")]=c(longitu[i],hori[j])
		m=m+1
		next
	#這裡對所有組合新增一條資料,其他值為NA
}
}
m=length(cross$longitude)+1
dataoo=cross[m:(dim(cross)[1]),]
poo=xtabs(~horizon+longitude,data=cross,drop.unused.levels=FALSE)
qoo=xtabs(~horizon+longitude,data=dataoo,drop.unused.levels=FALSE)
#qoo其實全為1,這裡可以檢驗一下前面步驟是否有誤
roo=poo-qoo
#roo即為全部變數都有的table

不過值得我們注意的是卡方檢驗等檢驗是建立在出現的特徵基礎上的(這其實是極大似然的思想,頻率為0我們預設概率為0,在獨立性假設的基礎上,不出現的變數其實已經不在聯合分佈裡面了),所以注意這裡假設檢驗值不是對全變量表而言的。

2)excel資料透視表建立table

這個方法也會出現剛才table中省略沒有的特徵組合的情形。

建立資料透視薄,在行標籤中選擇num和cluster,列表籤中選擇pay和orient,數值選擇code,值和欄位設定選擇計數。結果就直接出來了,優勢是簡單快捷,缺點自然是對於沒有出現的組合只能手動插入,如本資料中pay越高經常有orient根本沒有出現該樣本,這種方法table越大,手動操作就越費時。不多說了,上結果:

只是結果的一小部分。另外如果需要的是頻率列聯表,可以選擇值欄位設定>值顯示方式>佔總和的百分比,如果想看邊際的也可以選擇行或者列的百分比。不再贅述

3)reshape2建立列聯表

reshape2是在reshape更改的R包,但是如同hardley的其他包一樣改的很厲害,所以建議直接學reshape2,reshape原來的版本正在逐步退出舞臺,等有時間了,會有R包的相關文章更新。

library(reshape2)
#1.首先用reshape2實現資料列聯組合
cross=read.csv("cross.csv")
head(cross)
moo<-melt(cross,id.vars=c("num","cluster","orient","pay"),measure.vars=c("code"), variable.name="columnV", value.name="value")
str(moo)
aoo=acast(moo,num+cluster+pay+orient~columnV,drop=0)
boo=acast(moo,num+cluster+pay+orient~columnV,drop=1)
c("Laoo"=length(aoo),"Lboo"=length(boo),"diff"=length(aoo)-length(boo))


#2.將資料程式設計table的形式
#注意到aoo其實拆分成若干段,轉置疊在一起放就是table
colnames(aoo)
aoo=as.data.frame(aoo)
library(stringr)
length(aoo)
locate=list(array(t(rep(1,length(aoo))),(rep(1,length(aoo)))))


locate1<-function(x){
<span style="white-space:pre">	</span>y=paste(unlist(strsplit(x,"_"))[c(1,2)],collapse="_")
<span style="white-space:pre">	</span>return(y)
}
locate2<-function(x){
<span style="white-space:pre">	</span>y=paste(unlist(strsplit(x,"_"))[c(3,4)],collapse="_")
<span style="white-space:pre">	</span>#這裡用str_sub/str_extract並不成功,正則表示式不支援r的字串操作函式,有空再試一下,會出現在字串操作的文章裡面
<span style="white-space:pre">	</span>return(y)
}
longitude=sapply(rn,locate1,USE.NAMES=0)
horizon=sapply(rn,locate2,USE.NAMES=0)
number=length(unique(horizon))
head(horizon,n=120)
number#114個分成一行
#將aoo分行
class(aoo)
coo=matrix(NA,100,114)
colnames(coo)=unique(horizon)
rownames(coo)=unique(longitude)
coo[1,]=aoo[c(1:114),]
for(i in 1:100){
<span style="white-space:pre">	</span>coo[i,]=aoo[c((114*(i-1)+1):(114*i)),]
}
head(coo)
tail(coo)
dim(coo)
#coo就是想要的table,如果需要去margin.table和 prop.table進行矩陣運算就可以了
#prop除以所有元素和得到頻率列聯表
#頻率列聯錶行和列分別求和得到,邊際列聯表。

X_X_X_X,中X一次為num+cluster+pay+orient,同時也可以按到drop=0和drop=1的差為10243,可見如果手動進行補全是多麼痛苦的一件事情。

####################繼續更新,敬請期待!!!