R變量索引 - 什么時候使用 @或$
單細胞分析經常用到Seurat包,整個分析過程中的中間結果都在一個Seurat對象中存儲。常需要從里面提取對應數(shù)據(jù)進行后續(xù)分析,有時會用$,有時會用@,怎么選擇呢?
str函數(shù)是我們的好幫手,清晰展示對象層級結構和索引方式,如下,對應名字前出現(xiàn)@則用@索引(比如pbmc@assays),有$則用$索引(如pbmc@assays$RNA)。
>str(pbmc)
Formal class 'Seurat' [package "Seurat"] with 12 slots
..@ assays :List of 1
.. ..$ RNA:Formal class 'Assay' [package "Seurat"] with 7 slots
.. .. .. ..@ counts :Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
.. .. .. .. .. ..@ i : int [1:2282976] 29 73 80 148 163 184 186 227 229 230 ...
.. .. .. .. .. ..@ p : int [1:2701] 0 779 2131 3260 4220 4741 5522 6304 7094 7626 ...
.. .. .. .. .. ..@ Dim : int [1:2] 13714 2700
.. .. .. .. .. ..@ Dimnames:List of 2
.. .. .. .. .. .. ..$ : chr [1:13714] "AL627309.1" "AP006222.2" "RP11-206L10.2" "RP11-206L10.9" ...
.. .. .. .. .. .. ..$ : chr [1:2700] "AAACATACAACCAC" "AAACATTGAGCTAC" "AAACATTGATCAGC" "AAACCGTGCTTCCG" ...
.. .. .. .. .. ..@ x : num [1:2282976] 1 1 2 1 1 1 1 41 1 1 ...
.. .. .. .. .. ..@ factors : list()
.. .. .. ..@ data :Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
.. .. .. .. .. ..@ i : int [1:2282976] 29 73 80 148 163 184 186 227 229 230 ...
.. .. .. .. .. ..@ p : int [1:2701] 0 779 2131 3260 4220 4741 5522 6304 7094 7626 ...
.. .. .. .. .. ..@ Dim : int [1:2] 13714 2700
.. .. .. .. .. ..@ Dimnames:List of 2
.. .. .. .. .. .. ..$ : chr [1:13714] "AL627309.1" "AP006222.2" "RP11-206L10.2" "RP11-206L10.9" ...
.. .. .. .. .. .. ..$ : chr [1:2700] "AAACATACAACCAC" "AAACATTGAGCTAC" "AAACATTGATCAGC" "AAACCGTGCTTCCG" ...
.. .. .. .. .. ..@ x : num [1:2282976] 1 1 2 1 1 1 1 41 1 1 ...
.. .. .. .. .. ..@ factors : list()
.. .. .. ..@ scale.data : num[0 , 0 ]
.. .. .. ..@ key : chr "rna_"
.. .. .. ..@ var.features : logi(0)
.. .. .. ..@ meta.features:'data.frame': 13714 obs. of 0 variables
.. .. .. ..@ misc : NULL
..@ meta.data :'data.frame': 2700 obs. of 7 variables:
.. ..$ orig.ident : Factor w/ 1 level "YSX": 1 1 1 1 1 1 1 1 1 1 ...
.. ..$ nCount_RNA : num [1:2700] 2419 4903 3147 2639 980 ...
.. ..$ nFeature_RNA: int [1:2700] 779 1352 1129 960 521 781 782 790 532 550 ...
.. ..$ phases : Factor w/ 3 levels "G1","G2M","S": 1 1 1 1 3 1 1 1 1 1 ...
.. ..$ G1 : num [1:2700] 0.988 0.568 0.999 0.941 0.432 0.966 0.997 0.95 0.703 0.993 ...
.. ..$ S : num [1:2700] 0.216 0.692 0.415 0.091 0.302 0.082 0.034 0.175 0.167 0.004 ...
.. ..$ G2M : num [1:2700] 0.002 0.055 0.001 0.079 0.227 0.055 0.274 0.301 0.273 0.333 ...
..@ active.assay: chr "RNA"
..@ active.ident: Factor w/ 1 level "YSX": 1 1 1 1 1 1 1 1 1 1 ...
..@ project.name: chr "YSX"
具體操作如下:
# 查看metadata文件列信息
> colnames([email protected])
[1] "orig.ident" "nCount_RNA" "nFeature_RNA" "phases" "G1" "S" "G2M"
# 查看部分基因在部分細胞的原始reads counts
> pbmc@assays$RNA@counts[11:14,1:30]
Assay data with 13714 features for 2700 cells
First 10 features:
AL627309.1, AP006222.2, RP11-206L10.2, RP11-206L10.9, LINC00115, NOC2L,
KLHL17, PLEKHN1, RP11-54O7.17, HES4
那么$和@,到底是什么?有什么區(qū)別呢?
首先這兩個符號最大的區(qū)別在于:它們是兩個不同的面向對象系統(tǒng)的提取變量的符號。S3對象通常是列表,使用$索引;S4對象的不同slot使用@索引。
那什么是S3、S4呢?
要想知道S3、S4,首先得了解一下面向對象編程(object-oriented programming),它是一種編程范式,它將對象作為程序的基本單元, 將程序和數(shù)據(jù)封裝 (encapsulate) 其中, 以提高軟件的重用性, 靈活性和擴展性。
R語言中現(xiàn)有的S3類、S4類、以及R6類等都可以實現(xiàn)面向對象的編程范式。
與S3不同,S4有更正式的定義和創(chuàng)建對象的統(tǒng)一方法。
如何定義S4類?
S4類使用setClass()函數(shù)來定義
用R的術語來說,成員變量被稱為屬性。當定義一個類時,我們需要設置類的名字和成員變量(以及成員變量的屬性)。每個成員變量也會稱為一個slot。
例子一:定義S4類
setClass("student", slots=list(name="character", age="numeric", GPA="numeric"))
在上面的例子中,我們定義了一個名為student的新類,它有三個slot,分別是name (字符型), age 和 GPA (數(shù)值型)。
如何創(chuàng)建S4對象?
S4類使用new()函數(shù)來定義
例子二:創(chuàng)建S4對象
# create an object using new()
# provide the class name and value for slots
s <- new("student",name="John", age=21, GPA=3.5)
s
An object of class "student"
Slot "name":
[1] "John"
Slot "age":
[1] 21
Slot "GPA":
[1] 3.5
函數(shù)setClass()返回一個生成器函數(shù)。
這個生成器函數(shù)(通常與類同名)可用于創(chuàng)建新對象,它充當構造器。
> student <- setClass("student", slots=list(name="character", age="numeric", GPA="numeric"))
> student
class generator function for class “student” from package ‘.GlobalEnv’
function (...)
new("student", ...)
現(xiàn)在我們可以用構造函數(shù)創(chuàng)建新對象。
例子三:用構造函數(shù)創(chuàng)建S4對象
> student(name="John", age=21, GPA=3.5)
An object of class "student"
Slot "name":
[1] "John"
Slot "age":
[1] 21
Slot "GPA":
[1] 3.5
如何訪問和修改屬性?
正如使用$訪問list表的組件一樣,使用@訪問對象的屬性。
訪問屬性
s@name
[1] "John"
s@GPA
[1] 3.5
s@age
[1] 21
直接修改屬性
可以通過直接賦值修改屬性
# modify GPA
s@GPA <- 3.7
s
An object of class "student"
Slot "name":
[1] "John"
Slot "age":
[1] 21
Slot "GPA":
[1] 3.7
用slot()函數(shù)修改屬性
> slot(s,"name")
[1] "John"
> slot(s,"name") <- "Paul"
> s
An object of class "student"
Slot "name":
[1] "Paul"
Slot "age":
[1] 21
Slot "GPA":
[1] 3.7
方法和泛型函數(shù)
與S3類一樣,S4類的方法也屬于泛型函數(shù),而不是類本身。使用S4泛型與S3泛型非常相似。
可以使用showMethods()函數(shù)列出所有可用的S4通用函數(shù)和方法。
例子四:列出所有泛型函數(shù)
> showMethods()
Function: - (package base)
Function: != (package base)
...
Function: trigamma (package base)
Function: trunc (package base)
在交互模式中輸入對象名稱將會輸出它,用S4通用函數(shù)show()來達到同樣效果。
您可以在上面的列表中看到這個函數(shù),這個函數(shù)類似于S3 print()函數(shù)。
例子五:判斷一個函數(shù)是否是泛型函數(shù)。
> isS4(print)
[1] FALSE
> isS4(show)
[1] TRUE
我們可以使用showMethods(show)列出show泛型函數(shù)所有的方法。
例子六:列出泛型函數(shù)的所有方法。
> showMethods(show)
Function: show (package methods)
object="ANY"
object="classGeneratorFunction"
...
object="standardGeneric"
(inherited from: object="genericFunction")
object="traceable"
如何去寫你自己的方法?
我們可以使用setMethod()幫助函數(shù)寫自己的方法。
例如,我們可以實現(xiàn)show()泛型的類方法,如下所示。
setMethod("show",
"student",
function(object) {
cat(object@name, "\n")
cat(object@age, "years old\n")
cat("GPA:", object@GPA, "\n")
}
)
現(xiàn)在,如果我們像以前一樣以交互模式寫出對象的名稱,就會執(zhí)行上面的代碼。
參考來源
https://www.datamentor.io/r-programming/s4-class/
往期精品(點擊圖片直達文字對應教程)
后臺回復“生信寶典福利第一波”或點擊閱讀原文獲取教程合集

(請備注姓名-學校/企業(yè)-職務等)



























