sparseMatrix
1、首先来看一下问题的起源:
我有的数据是:
a <- rep(1:10, each = 100) #分组变量b <- sample(rep(1:4, 10000), 1000) #1:4之间的1000个随机数head(data.frame(a, b))
## a b## 1 1 3## 2 1 3## 3 1 3## 4 1 2## 5 1 3## 6 1 3
我希望对分组变量统计,组内取值的频率。 我使用了tapply函数:
c <- tapply(b, a, table)head(c)
## $`1`## ## 1 2 3 4 ## 25 15 31 29 ## ## $`2`## ## 1 2 3 4 ## 13 36 28 23 ## ## $`3`## ## 1 2 3 4 ## 20 27 28 25 ## ## $`4`## ## 1 2 3 4 ## 29 32 21 18 ## ## $`5`## ## 1 2 3 4 ## 22 31 17 30 ## ## $`6`## ## 1 2 3 4 ## 18 29 23 30
可以看出得到了,我想要的数据。但是tapply的输出是列表,我不太会将其转化为 data.frame
接下来使用Matrix包中的sparseMatrix得到了我想要的结果
library(Matrix)
## Warning: package 'Matrix' was built under R version 3.0.3
id <- unique(a)item <- 1:4i <- match(a, id)j <- match(b, item)c <- sparseMatrix(i, j, x = 1)c <- as.matrix(c)c <- data.frame(id, c) #I get a data.framehead(c)
## id X1 X2 X3 X4## 1 1 25 15 31 29## 2 2 13 36 28 23## 3 3 20 27 28 25## 4 4 29 32 21 18## 5 5 22 31 17 30## 6 6 18 29 23 30
由此产生了我需要的数据格式。
2、sparseMatrix函数的学习
example1
i <- c(1, 3:8)j <- c(2, 9, 6:10)x <- 7 * (1:7)(A <- sparseMatrix(i, j, x = x)) #从例子中可以看出,i,j是行列标号。x是取值
## 8 x 10 sparse Matrix of class "dgCMatrix"## ## [1,] . 7 . . . . . . . .## [2,] . . . . . . . . . .## [3,] . . . . . . . . 14 .## [4,] . . . . . 21 . . . .## [5,] . . . . . . 28 . . .## [6,] . . . . . . . 35 . .## [7,] . . . . . . . . 42 .## [8,] . . . . . . . . . 49
summary(A)
## 8 x 10 sparse Matrix of class "dgCMatrix", with 7 entries ## i j x## 1 1 2 7## 2 4 6 21## 3 5 7 28## 4 6 8 35## 5 3 9 14## 6 7 9 42## 7 8 10 49
str(A)
## Formal class 'dgCMatrix' [package "Matrix"] with 6 slots## ..@ i : int [1:7] 0 3 4 5 2 6 7## ..@ p : int [1:11] 0 0 1 1 1 1 2 3 4 6 ...## ..@ Dim : int [1:2] 8 10## ..@ Dimnames:List of 2## .. ..$ : NULL## .. ..$ : NULL## ..@ x : num [1:7] 7 21 28 35 14 42 49## ..@ factors : list()
example2
(AA <- sparseMatrix(c(1, 3:8), c(2, 9, 6:10), x = 7 * (1:7), dims = c(10, 20)))
## 10 x 20 sparse Matrix of class "dgCMatrix"## ## [1,] . 7 . . . . . . . . . . . . . . . . . .## [2,] . . . . . . . . . . . . . . . . . . . .## [3,] . . . . . . . . 14 . . . . . . . . . . .## [4,] . . . . . 21 . . . . . . . . . . . . . .## [5,] . . . . . . 28 . . . . . . . . . . . . .## [6,] . . . . . . . 35 . . . . . . . . . . . .## [7,] . . . . . . . . 42 . . . . . . . . . . .## [8,] . . . . . . . . . 49 . . . . . . . . . .## [9,] . . . . . . . . . . . . . . . . . . . .## [10,] . . . . . . . . . . . . . . . . . . . .
summary(AA) #dims可以比最大的行或列指标大
## 10 x 20 sparse Matrix of class "dgCMatrix", with 7 entries ## i j x## 1 1 2 7## 2 4 6 21## 3 5 7 28## 4 6 8 35## 5 3 9 14## 6 7 9 42## 7 8 10 49
example2
set.seed(1)(perm <- sample(1:7))
## [1] 2 3 6 4 1 7 5
(A1 <- sparseMatrix(i[perm], j[perm], x = x[perm])) #i,j,x可以在任意位置
## 8 x 10 sparse Matrix of class "dgCMatrix"## ## [1,] . 7 . . . . . . . .## [2,] . . . . . . . . . .## [3,] . . . . . . . . 14 .## [4,] . . . . . 21 . . . .## [5,] . . . . . . 28 . . .## [6,] . . . . . . . 35 . .## [7,] . . . . . . . . 42 .## [8,] . . . . . . . . . 49
stopifnot(identical(A, A1))
example3
(args <- data.frame(i = c(i, 1), j = c(j, 2), x = c(x, 2)))
## i j x## 1 1 2 7## 2 3 9 14## 3 4 6 21## 4 5 7 28## 5 6 8 35## 6 7 9 42## 7 8 10 49## 8 1 2 2
(Aa <- do.call(sparseMatrix, args)) #行列索引有重复位置的时候,相加
## 8 x 10 sparse Matrix of class "dgCMatrix"## ## [1,] . 9 . . . . . . . .## [2,] . . . . . . . . . .## [3,] . . . . . . . . 14 .## [4,] . . . . . 21 . . . .## [5,] . . . . . . 28 . . .## [6,] . . . . . . . 35 . .## [7,] . . . . . . . . 42 .## [8,] . . . . . . . . . 49
(A. <- do.call(sparseMatrix, c(args, list(use.last.ij = TRUE)))) #最后一个
## 8 x 10 sparse Matrix of class "dgCMatrix"## ## [1,] . 2 . . . . . . . .## [2,] . . . . . . . . . .## [3,] . . . . . . . . 14 .## [4,] . . . . . 21 . . . .## [5,] . . . . . . 28 . . .## [6,] . . . . . . . 35 . .## [7,] . . . . . . . . 42 .## [8,] . . . . . . . . . 49
example4
dn <- list(LETTERS[1:3], letters[1:5])(m <- sparseMatrix(i = c(3, 1, 3:2, 2:1), p = c(0:2, 4, 4, 6), x = 1:6, dimnames = dn)) #dimnames添加行列名 p为列指针,第一列为0
## 3 x 5 sparse Matrix of class "dgCMatrix"## a b c d e## A . 2 . . 6## B . . 4 . 5## C 1 . 3 . .
str(m)
## Formal class 'dgCMatrix' [package "Matrix"] with 6 slots## ..@ i : int [1:6] 2 0 1 2 0 1## ..@ p : int [1:6] 0 1 2 4 4 6## ..@ Dim : int [1:2] 3 5## ..@ Dimnames:List of 2## .. ..$ : chr [1:3] "A" "B" "C"## .. ..$ : chr [1:5] "a" "b" "c" "d" ...## ..@ x : num [1:6] 1 2 4 3 6 5## ..@ factors : list()