首頁 > 軟體

R語言將變數分組的3種方法範例(含cut函數說明)

2022-08-09 14:03:09

前言

在資料處理的過程中,我們有時候需要將連續的數值資料轉換為類別資料,比如將收入分成高、中和低三組,將學生成績分為優、良、中、及格和不及格五組。

本來將基於R語言,採用三種方法來實現;第一種是對變數直接進行重新賦值,第二種是使用within函數對語句進行組織,第三種是cut函數。

首先我們定義一個資料框,這個資料框包括學生姓名和數學成績兩個變數。

#定義資料框
mathScore <- data.frame(name=c("劉文濤","王宇翔","田思雨","徐麗娜","丁文彬","李志國","王智強","宋麗芳","袁芳芳","張建國"), math=c(85, 91, 74, 100, 82, 84, 78, 100, 51, 70))
head(mathScore)

接下來我們以90、80、70和60為界,將學生的數學成績分為優、良、中、及格和不及格五類。

方法一:直接對分組變數進行賦值

#方法一:直接對分組變數進行賦值
attach(mathScore)
mathScore$group1[math>=90]="優"
mathScore$group1[math>= 80 & math < 90] = "良"
mathScore$group1[math>= 70 & math < 80] = "中"
mathScore$group1[math>= 60 & math < 70] = "及格"
mathScore$group1[math < 60] = "不及格"
detach(mathScore)
head(mathScore)

這種方法較易理解,但使用attach函數可能會出現一些意想不到的問題,因此我們可以採用within函數,對程式碼進行優化,即方法二

方法二:使用within函數對變數進行分組

#方法二:使用within函數對變數進行分組
mathScore <- within(mathScore,{
  group2 <- NA
  group2[math>=90]="優"
  group2[math>= 80 & math < 90] = "良"
  group2[math>= 70 & math < 80] = "中"
  group2[math>= 60 & math < 70] = "及格"
  group2[math < 60] = "不及格"
})
head(mathScore)

在方法二中,要注意within函數的寫法,賦值語句要用大括號括起來,並且每條賦值語句佔一行。此外,在第一行首先定義了 group2 <- NA這個變數。

方法三:採用cut函數

採用cut函數也是較為常用的一種方法,但要注意的是需要對間段點的開閉進行設定。

#方法三:採用cut函數
mathScore$group3 <- cut(mathScore$math, breaks = c(-Inf, 60, 70, 80, 90, Inf), labels = c("不及格","及格","中","良","優"), right=FALSE)

在cut函數中:

  • breaks表示分界點,Inf表示無窮大; labels表示每個類別的名稱;
  • right=FALSE表示表示區間為左閉右開,即分段時不包括右邊的點,即良為[80,
    90);right=TRUE則表示左閉右開區間(預設是這種情形)

我們執行mathScore程式碼,就可以看到三種方法得到的結果是一致的。

關於cut函數引數的補充說明:

cut函數有兩個和分界點相關的引數,一個是include.lowest,一個是right,下面對這兩個引數進行詳細說明。

  • right引數:right=TRUE表示左閉右開區間,right=FALSE表示左開右閉區間
  • include.lowest引數:表示包括最小值或包括最大值

下面通過例子說明:

為了說明問題,我們把資料再重新定義一下,比原資料加入兩行:

#重新定義一下資料框
mathScore <- data.frame(name=c("劉文濤","王宇翔","田思雨","徐麗娜","丁文彬","李志國","王智強","宋麗芳","袁芳芳","張建國","張志偉","李明"), math=c(85, 91, 74, 100, 82, 84, 78, 100, 51, 70, 0, NA))
head(mathScore)

我們把之前程式碼改寫一下,把-Inf替換為0,把Inf替換為100,嘗試一下結果:

#問題程式碼範例
mathScore$group <- cut(mathScore$math, breaks = c(0, 60, 70, 80, 90, 100), labels = c("不及格","及格","中","良","優"), right=FALSE)
mathScore

我們可以看到輸出的結果如下:

name math group
1 劉文濤 85 良
2 王宇翔 91 優
3 田思雨 74 中
4 徐麗娜 100 < NA >
5 丁文彬 82 良
6 李志國 84 良
7 王智強 78 中
8 宋麗芳 100 < NA >
9 袁芳芳 51 不及格
10 張建國 70 中
11 張志偉 0 不及格
12 李明 NA < NA >

此結果有問題,因為100分不包括在內,因為 right=FALSE是左閉右開區間,這時就要改寫程式碼,加上引數include.lowest=TRUE

如下為正確程式碼範例:

#正確程式碼範例
mathScore$group <- cut(mathScore$math, breaks = c(0, 60, 70, 80, 90, 100), labels = c("不及格","及格","中","良","優"), right=FALSE, include.lowest=TRUE)
mathScore

這時的結果如下,我們發現是結果正確的:

name math group
1 劉文濤 85 良
2 王宇翔 91 優
3 田思雨 74 中
4 徐麗娜 100 優
5 丁文彬 82 良
6 李志國 84 良
7 王智強 78 中
8 宋麗芳 100 優
9 袁芳芳 51 不及格
10 張建國 70 中
11 張志偉 0 不及格
12 李明 NA < NA >

因為right=FALSE是左閉右開區間,加上引數include.lowest=TRUE後,意為把最大值的右端點包括了。

為了深入瞭解兩個端點引數的關係,我們嘗試動下如下兩段程式碼:

#對引數設定嘗試的程式碼
mathScore$group <- cut(mathScore$math, breaks = c(0, 60, 70, 80, 90, 100), labels = c("不及格","及格","中","良","優"), right=TRUE, include.lowest=FALSE)
mathScore

此程式碼為左閉右開區間,不包括最小值左側端點;

#對引數設定嘗試的程式碼
mathScore$group <- cut(mathScore$math, breaks = c(0, 60, 70, 80, 90, 100), labels = c("不及格","及格","中","良","優"), right=TRUE, include.lowest=TRUE)
mathScore

此程式碼為左閉右開區間,包括最小值區間左側端點。

因此,right和include.lowest總結如下:

right引數include.lowest引數備註
FALSETRUE左閉右開,包括最大值端點
TRUETRUE左開右閉,包括最小值端點
TRUEFALSE左開右閉,不包括最小值端點
FALSEFALSE左閉右開,包括最小值端點

其中,cut函數預設為right = TRUE, include.lowest=FALSE;

在實際的資料分析中,一般是將引數設定為right=FALSE, include.lowest=TRUE,即含下限不含上限,包括最大值區間右側端點。

總結

到此這篇關於R語言將變數分組的3種方法的文章就介紹到這了,更多相關R語言變數分組內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com