3.1 下标化
下标化在R语言中非常地强大,并且通常是高效率向量化的关键.
数组和数据框的维度下标化是独立的.
数组(包括矩阵)可以通过一组正整数进行下标化.下标化的索引矩阵的列数和所要查询的数组的维度相同–矩阵是两列.返回的结果是一个包含被选择对象一个向量(而非数组).
列表的下标化和其他向量类似.不过,有两个操作是列表特有的:’ ′和′[[′,这两种方式几乎差不多,不同之处在于′ ’后边跟的是一个列名而非字符串.
> mylist <- list(aaa=1:5, bbb=letters)
> mylist$aaa
[1] 1 2 3 4 5
> mylist[[’aaa’]]
[1] 1 2 3 4 5
> subv <- ’aaa’;
> mylist[[subv]]
[1] 1 2 3 4 5
我对你说谎而你不应该感到惊讶,使用”[[“的下标化同样适用于原子向量.如果你想获取一个单独的记录,那么这是一个比较安全的选择.如果你想得到的结果不少于一个记录,那么”[[“会让你失望了.
我们已经看到了(示例lsum中),下标化可以看做是非向量化的表现.
下面举个例子来说明下标化是怎样作为一个向量化的工具来使用的.想想这个问题:我们有一个矩阵amat,并且我们想产生一个只有amat一半行数的新矩阵,它的每一行的数值是amat连续两行数值的乘积.
用一个循环来实现的话是非常简单的:
bmat <- matrix(NA, nrow(amat)/2, ncol(amat))
for(i in 1:nrow(bmat))
{
bmat[i,] <- amat[2*i-1,] * amat[2*i,]
}
Note that we have avoided Circle 2 (page 12) by preallocating bmat.
Later iterations do not depend on earlier ones, so there is hope that we can
eliminate the loop. Subscripting is the key to the elimination:
请注意我们通过预分配的方式避免了轮回2里面的问题.
后边的操作并没有依赖前边的结果,所以我们是可以消除循环的.下标化正是消除循环的关键所在.
> bmat2 <- amat[seq(1, nrow(amat), by=2),] *
+ amat[seq(2, nrow(amat), by=2),]
> all.equal(bmat, bmat2)
[1] TRUE