抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

R 对象中值的选取是 R 应用的重要组成部分。而 R 的记号体系是最适合完成这项工作的系统。

值的选取(索引)

可以通过索引来选取指定的值。创建索引的主要方式有:

  • 正整数
  • 负整数
  • 空格
  • 逻辑值
  • 名称

正整数索引

可以使用类似 x[i]x[i, j] 的方式提取向量或列表的第 i 个元素,矩阵或数据框的第 i 行第 j 列的元素。ij 可以是整数(可以是双整型,数值为整数即可),也可以是数值向量。当索引为数值向量时,会提取对应行/列的数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> x <- 1:100
> x[5]
[1] 5
> m <- matrix(x, nrow = 10)
> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 11 21 31 41 51 61 71 81 91
[2,] 2 12 22 32 42 52 62 72 82 92
[3,] 3 13 23 33 43 53 63 73 83 93
[4,] 4 14 24 34 44 54 64 74 84 94
[5,] 5 15 25 35 45 55 65 75 85 95
[6,] 6 16 26 36 46 56 66 76 86 96
[7,] 7 17 27 37 47 57 67 77 87 97
[8,] 8 18 28 38 48 58 68 78 88 98
[9,] 9 19 29 39 49 59 69 79 89 99
[10,] 10 20 30 40 50 60 70 80 90 100
> m[5, 5]
[1] 45
> m[5, c(4,6)]
[1] 35 55

索引使用向量时,对向量中的元素是否重复不做要求,即可以在同一次取值中使用相同的索引值:

1
2
3
4
5
6
> m[5, c(4, 5, 6)]
[1] 35 45 55
> m[5, c(5, 5, 5)]
[1] 45 45 45
> m[5, c(6, 5, 4, 5)]
[1] 55 45 35 45

R 的索引是从 1 开始的,这一点与 C++ 等语言不同。

对于数据框,如果选取一列或一行数据,生成的对象是向量;但如果是选取多列和多行,生成的对象则是数据框。若想在使用索引取值时取消类型退化(即保持索引的单行或单列对象为数据框而不是向量),可以附加 drop = FALSE 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
> df <- data.frame(a=c(1,2,3),b=c("a","b","c"),c=c(TRUE,FALSE,TRUE))
> df
a b c
1 1 a TRUE
2 2 b FALSE
3 3 c TRUE
> df[1:2,1:2]
a b
1 1 a
2 2 b
> class(df[1:2,1:2])
[1] "data.frame"
> df[1:2,1]
[1] 1 2
> class(df[1:2,1])
[1] "numeric"
> df[1:2,1,drop = FALSE]
a
1 1
2 2
> class(df[1:2,1,drop = FALSE])
[1] "data.frame"

同样地,对矩阵或数组也有类似现象。

负整数索引

负整数索引的使用方式基本上与正整数索引类似,主要区别在于负整数索引指定的是不选取的行或列:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> m <- matrix(1:100, nrow = 10)
> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 11 21 31 41 51 61 71 81 91
[2,] 2 12 22 32 42 52 62 72 82 92
[3,] 3 13 23 33 43 53 63 73 83 93
[4,] 4 14 24 34 44 54 64 74 84 94
[5,] 5 15 25 35 45 55 65 75 85 95
[6,] 6 16 26 36 46 56 66 76 86 96
[7,] 7 17 27 37 47 57 67 77 87 97
[8,] 8 18 28 38 48 58 68 78 88 98
[9,] 9 19 29 39 49 59 69 79 89 99
[10,] 10 20 30 40 50 60 70 80 90 100
> m[-c(1:4,6:10), 4:6]
[1] 35 45 55

可以在不同的索引位置上使用正负不同的索引,但处于同一位置的索引正负必须相同:

1
2
3
4
> m[c(5,-5), 5]
Error in m[c(5, -5), 5] : only 0's may be mixed with negative subscripts
> m[c(4,-6), 5]
Error in m[c(4, -6), 5] : only 0's may be mixed with negative subscripts

零索引

使用数字 0 作索引本身并不会引起错误或警告,但因为返回的值不是数字 0 就是空对象,一般没有实际应用价值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
> m <- matrix(1:100, nrow = 10)
> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 11 21 31 41 51 61 71 81 91
[2,] 2 12 22 32 42 52 62 72 82 92
[3,] 3 13 23 33 43 53 63 73 83 93
[4,] 4 14 24 34 44 54 64 74 84 94
[5,] 5 15 25 35 45 55 65 75 85 95
[6,] 6 16 26 36 46 56 66 76 86 96
[7,] 7 17 27 37 47 57 67 77 87 97
[8,] 8 18 28 38 48 58 68 78 88 98
[9,] 9 19 29 39 49 59 69 79 89 99
[10,] 10 20 30 40 50 60 70 80 90 100
> m[0, 5]
integer(0)
> m[5, 0]
integer(0)
> m[0, 0]
<0 x 0 matrix>

空格索引

对于二维数据 xx[i]x[i,] 是有差别的,前者是指按列读取数据的第 i 个元素,后者是指第 i 行的全部元素:

1
2
3
4
5
6
7
8
9
> m <- matrix(1:100, nrow = 10)
> m[5]
[1] 5
> m[15]
[1] 15
> m[5,]
[1] 5 15 25 35 45 55 65 75 85 95
> m[,5]
[1] 41 42 43 44 45 46 47 48 49 50

该方法在 R 中被称为空格索引。

逻辑值索引

可以使用逻辑值向量作为索引来控制行或列的选取或非选取:

1
2
3
4
5
6
7
8
> x <- 1:10
> m <- matrix(1:100, nrow = 10)
> x[c(T, F, T, F, T, T, F, F, F, T)]
[1] 1 3 5 6 10
> m[5, c(F, F, F, T, T, T, F, F, F, F)]
[1] 35 45 55
> m[c(F, F, F, T, T, T, F, F, F, F), 5]
[1] 44 45 46

名称索引

如果对象具有名称属性,就可以使用对应的名称作为索引值来提取数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
> df <- data.frame(value=c(1, 10, 100),char=c("a","b","c"),status=c(TRUE,FALSE,TRUE))
> df
value char status
1 1 a TRUE
2 10 b FALSE
3 100 c TRUE
> df[,"char"]
[1] "a" "b" "c"
> df[1:2,"char"]
[1] "a" "b"
> df[3,c("value", "char")]
value char
3 100 c

$ 和 [[]]

除了上述的记号之外,$[[]] 也可用于某些特定的对象。

$ 可以用于提取数据框或列表对象中的值,例如:

1
2
3
4
5
6
7
8
9
10
11
12
> df <- data.frame(value=c(1, 10, 100),char=c("a","b","c"),status=c(TRUE,FALSE,TRUE))
> df
value char status
1 1 a TRUE
2 10 b FALSE
3 100 c TRUE
> df$value
[1] 1 10 100
> df$char
[1] "a" "b" "c"
> df$status
[1] TRUE FALSE TRUE

使用 $ 时名称属性不需要使用双引号

这种方法会返回一个向量。同样地,对于列表也是如此:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> lst <- list(value=c(1, 10, 100),char=c("a","b","c"),status=c(TRUE,FALSE,TRUE))
> lst
$value
[1] 1 10 100

$char
[1] "a" "b" "c"

$status
[1] TRUE FALSE TRUE

> lst$value
[1] 1 10 100
> lst$char
[1] "a" "b" "c"
> lst$status
[1] TRUE FALSE TRUE

使用单中括号 [] 索引会有许多限制,例如对上面的 lst 对象采取以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> lst$value
[1] 1 10 100
> lst[1]
$value
[1] 1 10 100

> class(lst$value)
[1] "numeric"
> class(lst[1])
[1] "list"
> sum(lst$value)
[1] 111
> sum(lst[1])
Error in sum(lst[1]) : invalid 'type' (list) of argument

可以看出,使用单中括号索引列表得到的是仍是列表,即使只有一个元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> lst <- list(value=1,char=c("a","b","c"),status=c(TRUE,FALSE,TRUE))
> lst
$value
[1] 1

$char
[1] "a" "b" "c"

$status
[1] TRUE FALSE TRUE

> class(lst$value)
[1] "numeric"
> class(lst[1])
[1] "list"

因此,对于列表中不含名称的元素(或不想使用名称),可以使用双中括号 [[]] 来提取数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> lst <- list(value=c(1, 10, 100),char=c("a","b","c"),status=c(TRUE,FALSE,TRUE))
> lst
$value
[1] 1 10 100

$char
[1] "a" "b" "c"

$status
[1] TRUE FALSE TRUE

> lst[1]
$value
[1] 1 10 100

> lst[[1]]
[1] 1 10 100
> class(lst[1])
[1] "list"
> class(lst[[1]])
[1] "numeric"

同样地,对于名称索引,也有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
> lst
$value
[1] 1 10 100

$char
[1] "a" "b" "c"

$status
[1] TRUE FALSE TRUE

> lst["char"]
$char
[1] "a" "b" "c"

> lst[["char"]]
[1] "a" "b" "c"
> class(lst["char"])
[1] "list"
> class(lst[["char"]])
[1] "character"

评论



This is a picture without description

This is a picture without description This is a picture without description This is a picture without description