如果要把一串數字做分類,例如要把溫度分低中高、年齡換成不同年齡層,在統計上來說就是把連續型的變數轉換成離散型的變數,常常會寫一堆if 和 else 來分類,像是用ifesle()來做:
例如要把1到20分成三組:1~5, 5~10, 10~20:
> (X <- 1:20)
例如要把1到20分成三組:1~5, 5~10, 10~20:
> (X <- 1:20)
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
> ifelse(X<=5, 1, ifelse(X <= 10, 2, 3))
[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3
其實R裡有個方便的函數cut() 可以試試,就不用再寫一堆if else囉!
[cut 的用法:1.待切割的數據,2.下刀處(要給頭尾),3切完後的類別]
提供原始資料和切點
> cut(X, c(0, 5, 10, 20)) ## breaks
[1] (0,5] (0,5] (0,5] (0,5] (0,5] (5,10] (5,10] (5,10] (5,10] (5,10]
[11] (10,20] (10,20] (10,20] (10,20] (10,20] (10,20] (10,20] (10,20] (10,20] (10,20]
Levels: (0,5] (5,10] (10,20]
提供原始資料+切點+新標籤
> cut(X, c(0, 5, 10, 20), c("S", "M", "L"))
[1] S S S S S M M M M M L L L L L L L L L L
Levels: S M L
把資料改成20到1,結果當然是倒過來的:
把資料改成20到1,結果當然是倒過來的:
> (x <-cut(20:1, c(0, 5, 10, 20), c("S", "M", "L")))
[1] L L L L L L L L L L M M M M M S S S S S
Levels: S M L
cut()傳回來的值是一種較複雜的物件Factor:不熟悉各種物件格式的朋友只要先記得,Factor其實是披上標籤外皮的數字,平時只看得到標籤(label),但用as.numeric()就可以看到他的真正數字了。Factor在建模時有些不錯的特性,須要另外寫一篇,先略過。
> as.numeric(x)
[1] 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 1 1 1 1 1
L對應3,M對應2,S對應1,Levels: S M L 裡就暗示了標籤對應數字的順序了。
如果只要文字符號,就把他變成Character吧!
> as.character(x)
[1] "L" "L" "L" "L" "L" "L" "L" "L" "L" "L" "M" "M" "M" "M" "M" "S" "S" "S" "S" "S"
比較下列兩行程式和結果看看Character和Factor的差別:
把原來Factor屬性的x依小到大排序,可以發現他是依潛在的數字在排序的(所以說他是批著文字皮的數字)。
把原來Factor屬性的x依小到大排序,可以發現他是依潛在的數字在排序的(所以說他是批著文字皮的數字)。
> sort(x)
[1] S S S S S M M M M M L L L L L L L L L L
變成Character以後做排序就是依照字母順序了。> sort(as.character(x))
[1] "L" "L" "L" "L" "L" "L" "L" "L" "L" "L" "M" "M" "M" "M" "M" "S" "S" "S" "S" "S"
其實如果不須要Factor的特性(或是不用label),cut()的好朋友findInterval()是一種更有效率的方法,他只傳回數值,而且給切點不用給頭尾。
> findInterval(1:20, c(5, 10))
[1] 0 0 0 0 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
分完類後,接著很多人會好奇每一類有幾個呢?這時就輪到table()上場了:
> table(x)
x
S M L
5 5 10
如果目的就是想知道一串數字分類後每類有幾個,那table()很慢,因為它有更複雜的功能(做交叉分析表cross table),所以在對單一數列計數表格,比起table(cut())的作法,畫直方圖(histgram)的函數hist()才是有效率和省記憶體的強者,一般資料不大的時候沒關係,但是如果是寫在迴圈且運算量大的程式裡....嘿嘿....
用plot=FALSE把圖關掉,hist()會輸出一堆東西,但是hist()$counts和table()的答案是一樣的。
用plot=FALSE把圖關掉,hist()會輸出一堆東西,但是hist()$counts和table()的答案是一樣的。
> hist(1:20, c(0, 5, 10, 20), plot=FALSE)$counts
[1] 5 5 10
重點1. cut() vs findInterval()
重點2. table(cut()) vs hist(..., plot=FALSE)
重點2. table(cut()) vs hist(..., plot=FALSE)
重點3. Reference: help(cut)
文章標籤
全站熱搜

謝謝!受益良多🙏
😊 有問題歡迎交流