博客 / 詳情

返回

R語言的數據結構與轉換

文章和代碼已經歸檔至【Github倉庫:https://github.com/timerring/dive-into-AI 】或者公眾號【AIShareLab】回覆 R語言 也可獲取。

任何數據分析的第一步都是按照所需要的格式創建數據集。在 R 中,這個任務包括兩個步驟:首先選擇一種數據結構來存儲數據,然後將數據輸入或者導入這個數據結構中。下面介紹 R 中用於存儲數據的多種數據結構。

R 的數據結構

  • 在大多數情況下,結構化的數據是一個由很多行和很多列組成的數據集。在 R 中,這種數據集被稱為數據框
  • 在學習數據框之前,我們先來認識一些用於存儲數據的數據結構:向量、因子、矩陣、數組和列表

1.1 向量

向量(vector)是用於存儲數值型、字符型、邏輯型數據的一維數組。標量可以看作是隻含有一個元素的向量。函數 c( ) 可用來創建向量,例如:

x1 <- c(2, 4, 1, -2, 5)
x2 <- c("one", "two", "three")
x3 <- c(TRUE, FALSE, TRUE, FALSE)

這裏 x1 是數值型向量,x2 是字符型向量,而 x3 是邏輯型向量。每一個向量中的數據類型必須一致。如果想創建有規律的向量,R 提供了一些簡便的操作和函數,例如:

x4 <- 1:5     # 等價於x4 <- c(1, 2, 3, 4, 5)
x5 <- seq(from = 2, to = 10, by = 2)  # 等價於x5 <- c(2, 4, 6, 8, 10)
x6 <- rep("a", times = 4)  # 等價於x6 <- c("a", "a", "a", "a")

有時候我們只想使用向量中的某個部分,即選取向量的子集。假設有一個從 3 到 100 的步長為 7 的整數向量,那麼第 5 個數的值是多少呢?

x <- seq(from = 3, to = 100, by = 7)
# 顯示第5個元素
x[5]
# 顯示第4,6,7個元素
x[c(4, 6, 7)]

在方括號“[ ]”中的數字被稱為 下標,它指定向量的索引位置。在上面的命令裏,x[5] 表示向量的第 5 個元素,其值為 31。

下標中的向量可以取負值,表示去除指定位置上的元素。例如,要去掉 x 的前4 個元素,可以輸入下面的代碼(注意命令裏的括號):

x[-(1:4)]

R 中的運算都是向量化的,例如:

weight <- c(68, 72, 57, 90, 65, 52)
height <- c(1.75, 1.80, 1.65, 1.90, 1.72, 1.65)
bmi <- weight / height ^ 2
bmi

在上面計算 bmi 的過程中,運算符“^”被循環使用了,所以計算的結果仍然是一個向量。如果參與運算的向量的長度不一致,R 會自動補全後計算,補全的規則是循環短的向量,同時給出警告信息。

a <- 1:5
b <- 1:3
a + b
# Warning message in a + b:
# “longer object length is not a multiple of shorter object length”
# 2 4 6 5 7
常用的統計函數
函數 描述
length(x) 求 x 中元素的個數
mean(x) 求 x 的算術平均值
median(x) 求 x 的中位數
var(x) 求 x 的樣本方差
sd(x) 求 x 的樣本標準差
range(x) 求 x 的全距
min(x) 求 x 的最小值
max(x) 求 x 的最大值
quantile(x) 求 x 的分位數
sum(x) 求 x 中所有元素的和
scale(x) 將 x 標準化

1.2 因子

一般來説,變量有數值型、名義型和有序型之分。

名義型變量是沒有順序關係的分類變量,例如人的性別、血型、民族等。而有序型變量是有層級和順序關係的分類變量,如患者的病情(較差、好轉、很好)。名義型變量和有序型變量在 R 中稱為因子(factor)

因子在 R 中非常重要,它決定了數據的展示和分析方式。數據存儲時因子經常以整數向量形式存儲。所以在進行數據分析之前,經常需要將它們用函數 factor( ) 轉換為因子。

# 先定義了一個變量 sex 表示性別,假設其取值 1 表示男性,2 表示女性。
sex <- c(1, 2, 1, 1, 2, 1, 2)
# 接着用函數 factor( ) 將變量 sex 轉換成了因子並存為對象 sex.f,其中參數 levels 表示原變量的分類標籤值,參數 labels 表示因子取值的標籤。
sex.f <- factor(sex,
                levels = c(1, 2),
                labels = c("Male", "Female"))
sex.f
# ============ 輸出 =============
# Male Female Male Male Female Male Female
# **Levels**:
# 'Male''Female' 

注意,這兩個參數在賦值時需要一一對應,R 會將它們相關聯。因子型變量與一般的字符型變量的區別就是它有一個水平(level)屬性。因子的屬性可以使用函數 levels( ) 查看:

levels(sex.f)
# 'Male''Female' 
改變因子水平的排列順序 → 改變參考組

在統計模型中,對於因子型變量,R 會將其第一個水平當作參考組。很多時候我們需要改變因子水平的排列順序以改變參考組,這可以通過兩種方法實現。第一種方法是在函數 factor( ) 中改變參數 levels 和 labels 的排列順序,例如:

sex.f1 <- factor(sex, levels = c(2, 1), labels = c("Female", "Male"))
sex.f1
# Male Female Male Male Female Male Female
# **Levels**:
# 'Female' 'Male'

第二種方法是使用函數 relevel( )

sex.f1 <- relevel(sex.f, ref = "Female")
sex.f1
# Male Female Male Male Female Male Female
# **Levels**:
# 'Female' 'Male'
序因子:ordered = TRUE

要表示有序因子,需要在函數 factor ( ) 裏指定參數 ordered = TRUE。例如:

status <- c(1, 2, 2, 3, 1, 2, 2)
status.f <- factor(
  status,
  levels = c(1, 2, 3),
  labels = c("Poor", "Improved", "Excellent"),
  ordered = TRUE
)
status.f
# PoorImprovedImprovedExcellentPoorImprovedImproved

1.3 矩陣

矩陣(matrix)是一個由行和列組成的二維數組。矩陣裏的每個元素具有相同的模式(數值型、字符型或邏輯型)。在大多數情況下,矩陣裏的元素是數值型的,它具有很多數學特性和運算方式,可以用來進行統計計算,例如因子分析、廣義線性模型等。

1.3.1 創建:matrix( )

函數 matrix( ) 常用於創建矩陣,例如:

M <- matrix(1:6, nrow = 2)
M

R 會根據向量的長度和參數 nrow 設定的行數自動計算列數。參數 byrow 默認為 FALSE,即按列將數值進行排列,如果需要按行排列,只需將參數 byrow 設為 TRUE

常見的矩陣運算都可以在R 中實現,如矩陣加法、矩陣乘法、求逆矩陣、矩陣轉置、求方陣的行列式、求方陣的特徵值和特徵向量等。

1.3.2 相乘:%*%

矩陣乘法中要求第一個矩陣的列數等於第二個矩陣的行數,其運算符為 %*%

先創建兩個矩陣:

mat1 <- matrix(1:6, nrow = 3)
mat1
mat2 <- matrix(5:10, nrow = 2)
mat2
# 函數dim( )可以得到矩陣的維數,即行數和列數
dim(mat1)
# 32
dim(mat2)
# 23
mat1 %*% mat2

1.3.3 轉置:t( )

矩陣的轉置運算就是把矩陣的行和列互換。例如,求矩陣 mat1 的轉置矩陣:

t(mat1)

1.3.4 行列式和逆矩陣:det( )、solve( )

求方陣的行列式逆矩陣分別可以使用函數 det( ) 和函數 solve( ) 實現,例如:

mat3 <- matrix(1:4, nrow = 2)
det(mat3)
# -2

1.3.5 按行、列求和或者求平均:rowSums、colSums、rowMeans、ColMeans

例如:

rowSums(mat1)
colSums(mat1)
rowMeans(mat1)
colMeans(mat1)

1.4 數組

通常所説的數組(array)指的是多維數組,它與矩陣類似,但是維數大於 2數組有一個特殊的維數(dim)屬性

下面的命令給一個向量加上維數後定義了一個數組,請注意數值的排列順序。

由於 notebook 上顯示的數組不太美好,建議使用 print()。以下代碼在顯示數組時會額外加上 print()。
A <- 1:24
dim(A) <- c(3, 4, 2)
# A # notebook 上數組顯示不太正常,使用 print() 可以解決
print(A)

上面的數組還可以通過函數 array( ) 創建,並給各個維度添加名稱和標籤。

dim1 <- c("A1", "A2", "A3")
dim2 <- c("B1", "B2", "B3", "B4")
dim3 <- c("C1", "C2")
print(array(1:24, dim = c(3, 4, 2), dimnames = list(dim1, dim2, dim3)))

1.5 列表

列表(list)是 R 中最靈活也最複雜的一種數據結構,它可以由不同類型的對象混合組成。例如,它可以是向量、數組、表格和任意類型對象的組合

list1 <- list(a = 1, b = 1:5, c = c("red", "blue", "green"))
list1
# $a
# 1
# $b
# 1 2 3 4 5
# $c
# 'red''blue''green'

在普通的數據分析中,創建列表並不是一項常見的任務。很多函數的返回值是一個列表。例如:

# 為了使結果具有可重複性,我們在該命令前用函數 set.seed( ) 設置了生成隨機數的種子。如果不設定種子,每次顯示的結果很可能不同。
set.seed(123)
# 用函數 rnorm( ) 從標準正態分佈中生成了一個由 10 個數組成的隨機樣本。
dat <- rnorm(10) 
# 用函數 boxplot( ) 對這個隨機樣本作**箱線圖**,並把結果保存為 bp。
bp <- boxplot(dat)
# 函數 class( ) 用於查看對象的類型,這裏 bp 是一個列表。
class(bp)
# 'list'

查看這個列表裏面的內容:

這裏列表 bp 包含了多個對象,如果想查看或使用某一個對象,只需用“$”符號引用。例如,要查看列表 bp 中的對象 stats 的內容,可以輸入 bp$stats 。對列表中其他對象感興趣,請移步 boxplot.stats 的説明文檔。

1.6 數據框

數據框(dataframe)是一個由行和列組成的二維結構,其中行表示觀測(observation)或記錄(record),列表示變量(variable)或指標(indicator)。數據框與 Excel、SAS 和SPSS 中的數據集類似。數據框看起來與矩陣很相似,而且矩陣的很多操作也適用於數據框,如子集的選擇。

與矩陣不同的是,數據框裏不同的列可以是不同模式(數值型、字符型等)的數據。數據框可以通過函數 data.frame( ) 創建。例如,下面的代碼創建了一個包含 5 個觀測對象、4 個變量的數據框:

ID <- 1:5
sex <- c("male", "female", "male", "female", "male")
age <- c(25, 34, 38, 28, 52)
pain <- c(1, 3, 2, 2, 3)      
pain.f <- factor(pain, levels = 1:3, labels = c("mild", "medium", "severe"))   
patients <- data.frame(ID, sex, age, pain.f)
patients

數據框本質上也是一種列表,要顯示或使用數據框的某一變量(列),可以使用 $ 符號加上變量名。例如:

patients$age
mean(patients$age)

大部分結構化的醫學數據集均以數據框的形式呈現,因此,數據框是最常處理的數據結構。

數據類型的轉換:is.、as.

在進行數據分析時,分析者需要對數據的類型熟稔於心,因為數據分析方法的選擇與數據的類型是有密切聯繫的。R 提供了一系列用於判斷某個對象的數據類型的函數,還提供了將某種數據類型轉換為另一種數據類型的函數。這些函數都存在於基本包 base 裏,下面列出了其中的一部分常用函數:

數據類型的判斷與轉換函數
判斷 轉換
is.numeric( ) as.numeric( )
is.character( ) as.character( )
is.logical( ) as.logical( )
is.factor( ) as.factor( )
is.vector( ) as.vector( )
is.matrix( ) as.matrix( )
is.array( ) as.array( )
is.data.frame( ) as.data.frame( )
is.list( ) as.list( )
is.table( ) as.table( )

is. 開頭的函數的返回值為 TRUE 或 FALSE,而以 as. 開頭的函數將對象轉換為相應的類型。例如:

x <- c(2, 5, 8)
is.numeric(x)
# TRUE
is.vector(x)
# TRUE
y <- as.character(x)
y
# '2''5''8'
is.numeric(y)
# FALSE
is.character(y)
# TRUE
z <- c(TRUE, FALSE, TRUE, FALSE)
is.logical(z)
# TRUE
as.numeric(z)
# 1 0 1 0

參考:趙軍《R語言醫學數據分析實戰》

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.