二维数据结构:Matrices和DataFrame
Matrix
简单的讲,给atomic vector加上维度信息,它就变成了array。如果维度信息是二维的,它就是matrix。也就是说,matrix只是array的一个特例,而array是从atomic vector扩展而来的。我们来试着构建一个matrix。
> vec <- 1:12
> mat <- matrix(vec, ncol = 3, nrow = 4) ##ncol == number of column, nrow == number of row
> mat
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 2 6 10
## [3,] 3 7 11
## [4,] 4 8 12
> ## 使用访问atomic vector的方法访问matrix
> mat[7]
## [1] 7
> ## 使用访问matrix的方法访问mat
> mat[3, 2] ## 7 == (2-1) * 4 + 3
## [1] 7
> ## 访问第二列
> mat[, 2]
## [1] 5 6 7 8
> ## 访问第一行
> mat[1, 2]
## [1] 5
> ## 访问第三列,但保持结果为matrix的形式
> mat[, 3, drop = FALSE]
## [,1]
## [1,] 9
## [2,] 10
## [3,] 11
## [4,] 12
> ## 改变第3行第2列的元素值为20
> mat[3, 2] <- 20
> mat <- matrix(vec, ncol = 3, nrow = 4, byrow = TRUE)
> mat
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
## [3,] 7 8 9
## [4,] 10 11 12
> dim(mat) ##matrix维度
## [1] 4 3
> nrow(mat) ## 有几行
## [1] 4
> ncol(mat) ## 有几列
## [1] 3
> length(mat) ## 这是继承的vector的属性
## [1] 12
> rownames(mat) <- letters[1:nrow(mat)] ## 行号
> colnames(mat) <- LETTERS[1:ncol(mat)] ## 列号
> mat
## A B C
## a 1 2 3
## b 4 5 6
## c 7 8 9
## d 10 11 12
> ## 构建一个array
> arr <- array(vec, c(2, 3, 2))
> arr
## , , 1
##
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
##
## , , 2
##
## [,1] [,2] [,3]
## [1,] 7 9 11
## [2,] 8 10 12
> dim(arr)
## [1] 2 3 2
合并matrix时,使用c()函数会将matrix视为atomic vector,所以得到还是一个atomic vector。如果这时还需要保持matrix的维度,那就需要使用到rbind()/cbind()。rbind == row bind; cbind == column bind。
> mat1 <- matrix(1:4, ncol = 2)
> mat2 <- matrix(4:1, ncol = 2)
> rbind(mat1, mat2) ## mat2接在mat1的下方
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
## [3,] 4 2
## [4,] 3 1
> cbind(mat1, mat2) ## mat2接在mat1的右侧
## [,1] [,2] [,3] [,4]
## [1,] 1 3 4 2
## [2,] 2 4 3 1
matrix转置使用t()函数(transpose)。
> mat <- matrix(1:12, ncol = 3)
> mat
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 2 6 10
## [3,] 3 7 11
## [4,] 4 8 12
> t(mat)
## [,1] [,2] [,3] [,4]
## [1,] 1 2 3 4
## [2,] 5 6 7 8
## [3,] 9 10 11 12
DataFrame
Data frame是R中最常被用到的数据结构。Data frame就是由一系列长度相等的vectors构成。它继承了vector的所有方法,包括atomic vector和list的方法,比如访问某一列可以使用'$'符号。它是2维的,它一样也有和matrix相同的方法,比如colnames(), rownames(), rbind(), cbind(), dim(), ncol(), nrow()等。
> df <- data.frame(A = 1:3, B = letters[1:3])
> df
## A B
## 1 1 a
## 2 2 b
## 3 3 c
> str(df)
## 'data.frame': 3 obs. of 2 variables:
## $ A: int 1 2 3
## $ B: Factor w/ 3 levels "a","b","c": 1 2 3
> df$A ##以列名访问元素
## [1] 1 2 3
> df[["B"]]
## [1] a b c
## Levels: a b c
> df[1, ] ##第一行
## A B
## 1 1 a
> df[, 2] ##第二列
## [1] a b c
## Levels: a b c
> dim(df)
## [1] 3 2
> cbind(df, C = 0)
## A B C
## 1 1 a 0
## 2 2 b 0
## 3 3 c 0
> rbind(df, data.frame(A = 4, B = "d")) ## 注意,在rbind时,需要保持列名一致
## A B
## 1 1 a
## 2 2 b
## 3 3 c
## 4 4 d
请注意,df的第二列原本输入的时候是character,但是在构建data.frame时,自动被转换为factors。这并不一定是我们需要的。如果想保留它原本的character属性,需要加上stringsAsFactors=FALSE参数。
> df <- data.frame(A = 1:3, B = letters[1:3], stringsAsFactors = FALSE)
> str(df)
## 'data.frame': 3 obs. of 2 variables:
## $ A: int 1 2 3
## $ B: chr "a" "b" "c"
之前在构建data.frame时,我们只尝试了使用atomic vector。换成list会如何呢?
> df <- data.frame(A = 1:3)
> df$B <- list(1, 1:2, letters[1:3])
> df
## A B
## 1 1 1
## 2 2 1, 2
## 3 3 a, b, c
但是如果直接使用list来构建data.frame,却不能直接成功。
> data.frame(A = 1:3, B = list(1, 1:2, letters[1:3]))
## Error: arguments imply differing number of rows: 1, 2, 3
我们需要使用I()函数来整合它。这里的I是AsIs的意思,即指输入是什么就是什么。
> data.frame(A = 1:3, B = I(list(1, 1:2, letters[1:3])))
## A B
## 1 1 1
## 2 2 1, 2
## 3 3 a, b, c
老师,您好,刚看到您讲的vector这里;我试着
a<-c(1,2,3)
typeof(a) 得到的类型却是double,class(a) 类型则是numeric,为什么不是integer,请老师解答。
你可以试一下a <- c(1L, 2L, 3L)
嗯,在rstudio里试了一下,确实可以了,在网上也找到了一篇博客,专门提到了这个问题,供大家参考:http://blog.sina.com.cn/s/blog_b37ea00701018uwo.html