正整數(shù)下標(biāo)
對(duì)向量x, 在后面加方括號(hào)和下標(biāo)可以訪問(wèn)向量的元素和子集。
設(shè)x <- c(1, 4, 6.25)。 x[2]取出第二個(gè)元素; x[2] <- 99修改第二個(gè)元素。 x[c(1,3)]取出第1、3號(hào)元素; x[c(1,3)] <- c(11, 13)修改第1、3號(hào)元素。 下標(biāo)可重復(fù)。 例如
> x <- c(1, 4, 6.25)
> x[2]
## [1] 4
> x[2] <- 99; x
## [1] 1.00 99.00 6.25
> x[c(1,3)]
## [1] 1.00 6.25
> x[c(1,3)] <- c(11, 13); x
## [1] 11 99 13
> x[c(1,3,1)]
## [1] 11 13 11
負(fù)整數(shù)下標(biāo)
負(fù)下標(biāo)表示扣除相應(yīng)的元素后的子集,如
> x <- c(1,4,6.25)
> x[-2]
## [1] 1.00 6.25
> x[-c(1,3)]
## [1] 4
負(fù)整數(shù)下標(biāo)不能與正整數(shù)下標(biāo)同時(shí)用來(lái)從某一向量中取子集, 比如,x[c(1,-2)]沒(méi)有意義。
空下標(biāo)與零下標(biāo)
x[]表示取x的全部元素作為子集。 這與x本身不同,比如
> x <- c(1,4,6.25)
> x[] <- 999
> x
## [1] 999 999 999
> x <- c(1,4,6.25)
> x <- 999
> x
## [1] 999
x[0]是一種少見(jiàn)的做法, 結(jié)果返回類(lèi)型相同、長(zhǎng)度為零的向量, 如numeric(0)。 相當(dāng)于空集。
當(dāng)與正整數(shù)下標(biāo)一起使用時(shí)會(huì)被忽略。 當(dāng)0與負(fù)整數(shù)下標(biāo)一起使用時(shí)也會(huì)被忽略。
下標(biāo)超界
設(shè)向量x長(zhǎng)度為, 則使用正整數(shù)下標(biāo)時(shí)下標(biāo)應(yīng)在中取值。 如果使用大于的下標(biāo), 讀取時(shí)返回缺失值,并不出錯(cuò)。 給超出的下標(biāo)元素賦值, 則向量自動(dòng)變長(zhǎng), 中間沒(méi)有賦值的元素為缺失值。 例如
> x <- c(1,4,6.25)
> x[5]
## [1] NA
> x
## [1] 1.00 4.00 6.25
> x[5] <- 9
> x
## [1] 1.00 4.00 6.25 NA 9.00
雖然R的語(yǔ)法對(duì)下標(biāo)超界不視作錯(cuò)誤, 但是這樣的做法往往來(lái)自不良的程序思路, 而且對(duì)程序效率有影響, 所以實(shí)際編程中應(yīng)避免下標(biāo)超界。
邏輯下標(biāo)
下標(biāo)可以是與向量等長(zhǎng)的邏輯表達(dá)式, 一般是關(guān)于本向量或者與本向量等長(zhǎng)的其它向量的比較結(jié)果,如
x <- c(1,4,6.25)
x[x > 3]
## [1] 4.00 6.25
取出x的大于3的元素組成的子集。
要注意的是,如果邏輯下標(biāo)中有缺失值, 對(duì)應(yīng)結(jié)果也是缺失值。 所以,在用邏輯下標(biāo)作子集選擇時(shí), 一定要考慮到缺失值問(wèn)題。正確的做法是加上!is.na前提, 如
> x <- c(1, 4, 6.25, NA)
> x[x > 2]
## [1] 4.00 6.25 NA
> x[!is.na(x) & x > 2]
## [1] 4.00 6.25
which()、which.min()、which.max()函數(shù)
函數(shù)which()可以用來(lái)找到滿足條件的下標(biāo), 如
> x <- c(3, 4, 3, 5, 7, 5, 9)
> which(x > 5)
## [1] 5 7
> seq(along=x)[x > 5]
## [1] 5 7
這里seq(along=x)會(huì)生成由x的下標(biāo)組成的向量。 用which.min()、which.max求最小值的下標(biāo)和最大值的下標(biāo), 不唯一時(shí)只取第一個(gè)。如
> which.min(x)
## [1] 1
> which.max(x)
## [1] 7
元素名
向量可以為每個(gè)元素命名。如
> ages <- c("李明"=25,"田曉霞"=21,"孫少平"=22)
> ages
## 李明 田曉霞 孫少平
25 21 22
或者
> ages <- c(25,21,22)
> names(ages)<- c("李明","田曉霞","孫少平")
> ages
## 李明 田曉霞 孫少平
25 21 22
或者
> ages <- setNames(c(25,21,22),c("李明","田曉霞","孫少平"))
> ages
## 李明 田曉霞 孫少平
25 21 22
這時(shí)可以用元素名或元素名向量作為向量的下標(biāo),如
> ages["李明"]
## 李明
25
> ages["李明"] <- 11
> ages
## 李明 田曉霞 孫少平
11 21 22
這實(shí)際上建立了字符串到數(shù)值的映射表。
用字符串作為下標(biāo)時(shí), 如果該字符串不在向量的元素名中, 讀取時(shí)返回缺失值結(jié)果, 賦值時(shí)該向量會(huì)增加一個(gè)元素并以該字符串為元素名。
帶有元素名的向量也可以是字符型或其它基本類(lèi)型,如
> sex <- c("孫少平"="男","田曉霞"="女")
> sex
## 孫少平 田曉霞
"男" "女"
除了給向量元素命名外, 在矩陣和數(shù)據(jù)框中還可以給行、列命名, 這會(huì)使得程序的擴(kuò)展更為容易和安全。
R允許僅給部分元素命名, 這時(shí)其它元素名字為空字符串。 不同元素的元素名一般應(yīng)該是不同的, 否則在使用元素作為下標(biāo)時(shí)會(huì)發(fā)生誤讀, 但是R語(yǔ)法允許存在重名。
用unname(x)返回去掉了元素名的x的副本, 用names(x) <- NULL可以去掉x的元素
> unname(ages)
## [1] 11 21 22
> ages
## 李明 田曉霞 孫少平
11 21 22
> names(ages) <- NULL
> ages
## [1] 11 21 22
用R向量下標(biāo)作映射
R在使用整數(shù)作為向量下標(biāo)時(shí),允許使用重復(fù)下標(biāo), 這樣可以把數(shù)組x看成一個(gè)的整數(shù)到 x[1], x[2], , x[n]的一個(gè)映射表, 其中是x的長(zhǎng)度。 比如,某商店有三種禮品,編號(hào)為1,2,3, 價(jià)格分別為68, 88和168。令
> price.map <- c(68, 88, 168)
設(shè)某個(gè)收銀員在一天內(nèi)分別售出禮品編號(hào)為3,2,1,1,2,2,3, 可以用如下的映射方式獲得售出的這些禮品對(duì)應(yīng)的價(jià)格:
> items <- c(3,2,1,1,2,2,3)
> y <- price.map[items]; print(y)
## [1] 168 88 68 68 88 88 168
R向量可以用字符型向量作下標(biāo), 字符型下標(biāo)也允許重復(fù), 所以可以把帶有元素名的R向量看成是元素名到元素值的映射表。 比如,設(shè)sex為10個(gè)學(xué)生的性別(男、女)
> sex <- c("男", "男", "女", "女", "男", "女", "女", "女", "女", "男")
希望把每個(gè)學(xué)生按照性別分別對(duì)應(yīng)到藍(lán)色和紅色。 首先建立一個(gè)R向量當(dāng)作映射
> sex.color <- c("男"="blue", "女"="red")
用R向量sex.color當(dāng)作映射,可以獲得每個(gè)學(xué)生對(duì)應(yīng)的顏色
> cols <- sex.color[sex]; print(cols)
## 男 男 女 女 男 女 女 女 女 男
## "blue" "blue" "red" "red" "blue" "red" "red" "red" "red" "blue"
這樣的映射結(jié)果中帶有不必要的元素名, 用unname()函數(shù)可以去掉元素名,如
> unname(cols)
## [1] "blue" "blue" "red" "red" "blue" "red" "red" "red" "red" "blue"
集合運(yùn)算
可以把向量x看成一個(gè)集合,但是其中的元素允許有重復(fù)。 用unique(x)可以獲得x的所有不同值。如
> unique(c(1, 5, 2, 5))
## [1] 1 5 2
用a %in% x判斷a的每個(gè)元素是否屬于向量x,如
> 5 %in% c(1,5,2)
## [1] TRUE
> c(5,6) %in% c(1,5,2)
## [1] TRUE FALSE
與%in運(yùn)算符類(lèi)似, 函數(shù)match(x, table)對(duì)向量x的每個(gè)元素, 從向量table中查找其首次出現(xiàn)位置并返回這些位置。 沒(méi)有匹配到的元素位置返回NA_integer_(整數(shù)型缺失值)。 如
> match(5, c(1,5,2))
## [1] 2
> match(5, c(1,5,2,5))
## [1] 2
> match(c(2,5), c(1,5,2,5))
## [1] 3 2
> match(c(2,5,0), c(1,5,2,5))
## [1] 3 2 NA
用intersect(x,y)求交集,結(jié)果中不含重復(fù)元素,如
> intersect(c(5, 7), c(1, 5, 2, 5))
## [1] 5
用union(x,y)求并集,結(jié)果中不含重復(fù)元素,如
> union(c(5, 7), c(1, 5, 2, 5))
## [1] 5 7 1 2
用setdiff(x,y)求差集,即x的元素中不屬于y的元素組成的集合, 結(jié)果中不含重復(fù)元素,如
> setdiff(c(5, 7), c(1, 5, 2, 5))
## [1] 7
用setequal(x,y)判斷兩個(gè)集合是否相等, 不受次序與重復(fù)元素的影響,如
> setequal(c(1,5,2), c(2,5,1))
## [1] TRUE
> setequal(c(1,5,2), c(2,5,1,5))
## [1] TRUE
練習(xí)
設(shè)文件class.csv內(nèi)容如下:
name,sex,age,height,weight
Alice,F,13,56.5,84
Becka,F,13,65.3,98
Gail,F,14,64.3,90
Karen,F,12,56.3,77
Kathy,F,12,59.8,84.5
Mary,F,15,66.5,112
Sandy,F,11,51.3,50.5
Sharon,F,15,62.5,112.5
Tammy,F,14,62.8,102.5
Alfred,M,14,69,112.5
Duke,M,14,63.5,102.5
Guido,M,15,67,133
James,M,12,57.3,83
Jeffrey,M,13,62.5,84
John,M,12,59,99.5
Philip,M,16,72,150
Robert,M,12,64.8,128
Thomas,M,11,57.5,85
William,M,15,66.5,112
用如下程序可以把上述文件讀入為R數(shù)據(jù)框d.class, 并取出其中的name和age列到變量name和age中:
> d.class <- read.csv("class.csv", header=TRUE, stringsAsFactors=FALSE)
> name <- d.class[,"name"]
> age <- d.class[,"age"]
> age
[1] 13 13 14 12 12 15 11 15 14 14 14 15 12 13 12 16 12 11 15
> d.class
name sex age height weight
1 Alice F 13 56.5 84.0
2 Becka F 13 65.3 98.0
3 Gail F 14 64.3 90.0
4 Karen F 12 56.3 77.0
5 Kathy F 12 59.8 84.5
6 Mary F 15 66.5 112.0
7 Sandy F 11 51.3 50.5
8 Sharon F 15 62.5 112.5
9 Tammy F 14 62.8 102.5
10 Alfred M 14 69.0 112.5
11 Duke M 14 63.5 102.5
12 Guido M 15 67.0 133.0
13 James M 12 57.3 83.0
14 Jeffrey M 13 62.5 84.0
15 John M 12 59.0 99.5
16 Philip M 16 72.0 150.0
17 Robert M 12 64.8 128.0
18 Thomas M 11 57.5 85.0
19 William M 15 66.5 112.0
-
求出age中第3, 5, 7號(hào)的值;
> age[c(3,5,7)] ## [1] 14 12 11 -
用變量age, 求出達(dá)到15歲及以上的那些值;
> age[age>=15] ## [1] 15 15 15 16 15 -
用變量name和age, 求出Mary與James的年齡。
> set <- setNames(age,name) > set[match(c("Mary","James"),name)] Mary James 15 12 求age中除Mary與James這兩人之外的那些人的年齡值,保存到變量age1中。
> a <- match(c("Mary","James"),name)
> b <- (1:length(name))
> a
[1] 6 13
> b
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
> age1 <- set[setdiff(b,a)]
> age1
Alice Becka Gail Karen Kathy Sandy Sharon Tammy Alfred Duke Guido
13 13 14 12 12 11 15 14 14 14 15
Jeffrey John Philip Robert Thomas William
13 12 16 12 11 15