R語言中的資料篩選索引
data_select
Xiaojia Zhang
R中資料篩選方法綜述
利用整數下標形式索引
x=c(1:10)
x
## [1] 1 2 3 4 5 6 7 8 9 10
x[4]
## [1] 4
x[1:3]
## [1] 1 2 3
x[-3]
## [1] 1 2 4 5 6 7 8 9 10
x[-c(1:3)]
## [1] 4 5 6 7 8 9 10
y=c(1:20)
dim(y)=c(4,5)
y
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
y[2,3]
## [1] 10
y[-1,-1]
## [,1] [,2] [,3] [,4]
## [1,] 6 10 14 18
## [2,] 7 11 15 19
## [3,] 8 12 16 20
y[1:2,1:2]
## [,1] [,2]
## [1,] 1 5
## [2,] 2 6
y[-c(1,2),-c(1:2)]
## [,1] [,2] [,3]
## [1,] 11 15 19
## [2,] 12 16 20
利用列名索引
x=c(1:5)
y=2*x
z=cbind(x,y)
z
## x y
## [1,] 1 2
## [2,] 2 4
## [3,] 3 6
## [4,] 4 8
## [5,] 5 10
z[1,"x"]
## x
## 1
z[1,1]
## x
## 1
z[,"y"]
## [1] 2 4 6 8 10
z[1,c("x","y")]
## x y
## 1 2
z[,c("x","y")]
## x y
## [1,] 1 2
## [2,] 2 4
## [3,] 3 6
## [4,] 4 8
## [5,] 5 10
利用邏輯向量索引
在利用邏輯向量索引時,R將查詢邏輯值為TRUE元素的下標,並索引該下標元素的值,而不包括FALSE的值
x=c(1:10)
set.seed(1)
s=sample(c(TRUE,FALSE),10,replace = TRUE)
x
## [1] 1 2 3 4 5 6 7 8 9 10
s
## [1] TRUE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE
x[s]
## [1] 1 2 5 10
!s
## [1] FALSE FALSE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE
x[!s]
## [1] 3 4 6 7 8 9
利用條件表示式,實質上也是利用邏輯向量
注意到,所有關於向量的表示式返回的均是邏輯向量
set.seed(1)
x=sample(1:100,10,replace = FALSE)
x
## [1] 27 37 57 89 20 86 97 62 58 6
#有關向量的表示式返回的均是邏輯向量
y=(x>30)
y
## [1] FALSE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE FALSE
x[x>30]
## [1] 37 57 89 86 97 62 58
x[y]
## [1] 37 57 89 86 97 62 58
#!y表示將y這一邏輯向量翻轉,TRUE變為FALSE,FALSE變為TRUE, 與之對應的是在整數索引中,我們用的‘-’,如x[-c(1:3)]
x[!y]
## [1] 27 20 6
#which函式返回表示式邏輯向量中TRUE的索引,
which(x>30)
## [1] 2 3 4 6 7 8 9
x[which(x>30)]
## [1] 37 57 89 86 97 62 58
x[-which(x>30)]
## [1] 27 20 6
其他例子
#對於具有很多列的資料框,只排除其中較少的列,該如何通過列名來實現
x=c(1:5)
y=2*x
z=c("January","February","March","April","May")
S=data.frame(x,y,z)
S
## x y z
## 1 1 2 January
## 2 2 4February
## 3 3 6 March
## 4 4 8 April
## 5 5 10 May
names(S)=c("fir","sec","thi")
#選擇不包括“thi”列的資料,
delete_=names(S)%in% c("thi")
delete_
## [1] FALSE FALSE TRUE
S[c("fir","sec")]
## fir sec
## 1 1 2
## 2 2 4
## 3 3 6
## 4 4 8
## 5 5 10
S[!delete_]
## fir sec
## 1 1 2
## 2 2 4
## 3 3 6
## 4 4 8
## 5 5 10
利用subset選擇資料
set.seed(1)
age=sample(18:60,15,replace=TRUE)
salary=sample(3000:12000,15,replace = TRUE)
age
## [1] 29 34 42 57 26 56 58 46 45 20 26 25 47 3451
salary
## [1] 7479 9459 11928 6420 9997 11413 4909 8865 4130 5405 6475
## [12] 3120 6441 10828 6063
people=data.frame(age,salary)
people
## age salary
## 1 29 7479
## 2 34 9459
## 3 42 11928
## 4 57 6420
## 5 26 9997
## 6 56 11413
## 7 58 4909
## 8 46 8865
## 9 45 4130
## 10 20 5405
## 11 26 6475
## 12 25 3120
## 13 47 6441
## 14 34 10828
## 15 51 6063
people[age>25&age<45,"salary"]
## [1] 7479 9459 11928 9997 6475 10828
people_select=subset(people,age>25&age<45,c("age","salary"))
people_select
## age salary
## 1 29 7479
## 2 34 9459
## 3 42 11928
## 5 26 9997
## 11 26 6475
## 14 34 10828
綜合應用
問題一,已知一個向量X,要求將該向量隨機地劃分為兩個長度相等的向量(假設向量長度為偶數)
問題二,已知一個向量,要求將該向量隨機地劃分為兩個向量,並且兩個向量的長度也是隨機的
#對於問題一,涉及到隨機問題,我們可考慮利用sample()函式來產生隨機數,即隨機的不放回地產生該向量的索引,並用該索引數構成的向量來劃分向量
set.seed(1)
x=c(1:20)
index=sample(1:length(x),length(x)/2,replace = FALSE)
index #索引向量
## [1] 6 8 11 16 4 14 15 9 19 1
x1=x[index]
x1
## [1] 6 8 11 16 4 14 15 9 19 1
x2=x[-index]#在索引向量前加‘-’,表示返回這些索引的元素值
x2
## [1] 2 3 5 7 1012 13 17 18 20
#對於問題二,由於要求向量分割長度隨機,因此考慮每一個索引值是否選擇也應該是隨機的情況,這種情況的話通過整數索引難以實現,但我們可以利用邏輯向量的方式輕鬆實現這一點,注意此時產生的隨機數是決定向量中每一個元素是否被選擇的邏輯值TRUEorFALSE,所以應採用又放回抽樣
luoji=sample(c(TRUE,FALSE),length(x),replace = TRUE)
luoji
## [1] TRUE TRUE FALSE TRUE FALSE TRUE FALSE FALSE TRUE FALSE FALSE
## [12] TRUE FALSE TRUE TRUE TRUE TRUE TRUE FALSE TRUE
x1=x[luoji]
x1
## [1] 1 2 4 6 9 12 14 15 16 17 18 20
x2=x[!luoji]
x2
## [1] 3 5 7 8 10 11 13 19