[关闭]
@evilking 2017-10-15T10:37:46.000000Z 字数 4998 阅读 1174

R基础篇

数据框

数据框同样是R中非常重要也是最常用的数据结构之一,一般可以用来操作数据表

从直观上看,数据框类似于矩阵,有行和列两个维度,与矩阵不同的是,数据框的每列可以具有不同的模式(mode),例如一列是数值型数据,另一列是字符型数据

从技术层面而言,数据框是每个组件长度都相等的列表,按列排列存储

创建数据框

  1. > id <- c(1:5)
  2. > name <- c("Tom","Jack","Rose","Ketty","Hello")
  3. > salary <- seq(from=2000,to=6000,by=1000)
  4. > (x <- data.frame(id,name,salary,stringsAsFactors = FALSE))
  5. id name salary
  6. 1 1 Tom 2000
  7. 2 2 Jack 3000
  8. 3 3 Rose 4000
  9. 4 4 Ketty 5000
  10. 5 5 Hello 6000
  11. > names(x)
  12. [1] "id" "name" "salary"
  13. >

实例代码的前三句好理解,就是分别生成了三个长度为5的向量,最后一句就是利用data.frame()来生成数据框

该函数的前面三个参数表示三个向量,作为数据源来填充数据框,按列排列,每个向量在数据框中就成了一个字段,字段名即为向量对象的字符串名

最后一个stringsAsFactors=FALSE参数就表示不将字符串自动转换为“因子”(factor),保留字符串的属性,该参数默认去TRUE,表示会自动将字符串转换为“因子”

关于因子的概念我们在后面篇幅中专门讲解


一般使用read.table()等函数从文件中读取数据,读取的结果也是一个数据框,例如我们在R的工作空间中创建一个文件my_data_frame.txt,内容为:

  1. "id" "name" "salary"
  2. 1 "Tom" 2000
  3. 2 "Jack" 3000
  4. 3 "Rose" 4000
  5. 4 "Ketty" 5000
  6. 5 "Hello" 6000

则用R代码去读取这个文件:

  1. > y <- read.table("my_data_frame.txt",header = TRUE)
  2. > y
  3. id name salary
  4. 1 1 Tom 2000
  5. 2 2 Jack 3000
  6. 3 3 Rose 4000
  7. 4 4 Ketty 5000
  8. 5 5 Hello 6000
  9. > class(y) #查看读取数据后的结果对象的类型
  10. [1] "data.frame"
  11. >

对象y的第一列显示的是行索引,第一行表示的是列的字段名,查看对象y的数据类型为"data.frame",可知读取文件数据的结果创建了一个数据框

这里使用的read.table()函数部分,在后面的基础篇之文件数据的存储于读取的文章中会详细讲解,现在可以暂时不用过多理会


数据框的值操作

访问数据框

  1. > x #使用的数据框
  2. id name salary
  3. 1 1 Tom 2000
  4. 2 2 Jack 3000
  5. 3 3 Rose 4000
  6. 4 4 Ketty 5000
  7. 5 5 Hello 6000
  8. > x[[1]] #按数字索引的方式访问数据框字段
  9. [1] 1 2 3 4 5
  10. > x[["name"]] #按字段名的方式访问数据框
  11. [1] "Tom" "Jack" "Rose" "Ketty" "Hello"
  12. > x$salary #用$符合访问字段
  13. [1] 2000 3000 4000 5000 6000
  14. > x[,1] #使用类似于访问矩阵的方式访问数据框
  15. [1] 1 2 3 4 5
  16. > class(x[,1])
  17. [1] "integer"
  18. > x[2:4,2] #用类似于矩阵的方式提取子数据框
  19. [1] "Jack" "Rose" "Ketty"
  20. > mode(x[2:4,2]) #自动降维成向量
  21. [1] "character"
  22. > x[2:4,2,drop = FALSE] #使用drop =FALSE参数保持数据框属性
  23. name
  24. 2 Jack
  25. 3 Rose
  26. 4 Ketty
  27. > class(x[2:4,2,drop = FALSE])
  28. [1] "data.frame"
  29. >
  30. > x[2:4,2:3] #子数据框自动变成了列表
  31. name salary
  32. 2 Jack 3000
  33. 3 Rose 4000
  34. 4 Ketty 5000
  35. > mode(x[2:4,2:3])
  36. [1] "list"
  37. > x[1:2] #类似于列表,以单括号的方式访问数据框,结果为子数据框
  38. id name
  39. 1 1 Tom
  40. 2 2 Jack
  41. 3 3 Rose
  42. 4 4 Ketty
  43. 5 5 Hello
  44. > class(x[["name"]]) #查看字段的类型
  45. [1] "character"
  46. > class(x[1]) #单括号索引访问结果为子数据框
  47. [1] "data.frame"
  48. > str(x) #使用str()函数查看对象的内部结构
  49. 'data.frame': 5 obs. of 3 variables:
  50. $ id : int 1 2 3 4 5
  51. $ name : chr "Tom" "Jack" "Rose" "Ketty" ...
  52. $ salary: num 2000 3000 4000 5000 6000
  53. >

上述实例代码展示了四种访问数据框的方法,可以使用[[1]]数字索引访问第几列元素,使用[["name"]]字段名索引访问指定列元素,使用$salary$符合的方式访问指定列元素,以及使用类似于[2:4,2]矩阵取值操作的方式访问数据框元素,这也是提取子数据框的方法

其中x[1:2]的用法类似于列表,可以提取序列索引对应的列,结果的数据类型为数据框

str()函数很重要,它可以方便的查看R中所以对象的内部结构,包括多少行数据、多少个字段、字段名、每个字段的值是什么,都可以从中清楚的获知。当我们在用别人的库时,函数调用返回的对象不知道有哪些变量,就可以使用该函数查看


向数据框中添加列或行

  1. > x
  2. id name salary
  3. 1 1 Tom 2000
  4. 2 2 Jack 3000
  5. 3 3 Rose 4000
  6. 4 4 Ketty 5000
  7. 5 5 Hello 6000
  8. > (x <- rbind(x,list(6,"World",7000))) #行绑定,向数据框中添加新行
  9. id name salary
  10. 1 1 Tom 2000
  11. 2 2 Jack 3000
  12. 3 3 Rose 4000
  13. 4 4 Ketty 5000
  14. 5 5 Hello 6000
  15. 6 6 World 7000
  16. > (x <- cbind(x,flag = TRUE,new = x$id)) #列绑定,向数据框中添加新列,这里还用到了循环补齐
  17. id name salary flag new
  18. 1 1 Tom 2000 TRUE 1
  19. 2 2 Jack 3000 TRUE 2
  20. 3 3 Rose 4000 TRUE 3
  21. 4 4 Ketty 5000 TRUE 4
  22. 5 5 Hello 6000 TRUE 5
  23. 6 6 World 7000 TRUE 6
  24. > x[4:5] <- NULL #删除序列索引指定的列
  25. > x
  26. id name salary
  27. 1 1 Tom 2000
  28. 2 2 Jack 3000
  29. 3 3 Rose 4000
  30. 4 4 Ketty 5000
  31. 5 5 Hello 6000
  32. 6 6 World 7000
  33. >

类似于矩阵的添加行或列,数据框也是使用的rbind()函数添加新行,使用cbind()函数添加新列;当要删除列时,可将对应的列设为NULL即可
————————————————————————————————————
修改列名

  1. > x
  2. id name salary
  3. 1 1 Tom 2000
  4. 2 2 Jack 3000
  5. 3 3 Rose 4000
  6. 4 4 Ketty 5000
  7. 5 5 Hello 6000
  8. 6 6 World 7000
  9. > names(x) <- c(names(x)[1:2],"old_salary") #修改第三列字段的字段名
  10. > x
  11. id name old_salary
  12. 1 1 Tom 2000
  13. 2 2 Jack 3000
  14. 3 3 Rose 4000
  15. 4 4 Ketty 5000
  16. 5 5 Hello 6000
  17. 6 6 World 7000
  18. > names(x) <- NULL #删除字段名
  19. > x
  20. 1 1 Tom 2000
  21. 2 2 Jack 3000
  22. 3 3 Rose 4000
  23. 4 4 Ketty 5000
  24. 5 5 Hello 6000
  25. 6 6 World 7000
  26. >

数据框也可以用names()函数来查看和修改字段名,若要删除字段名,只需要将names(x)设为NULL即可


数据框上应用函数

  1. > x
  2. 1 1 Tom 2000
  3. 2 2 Jack 3000
  4. 3 3 Rose 4000
  5. 4 4 Ketty 5000
  6. 5 5 Hello 6000
  7. 6 6 World 7000
  8. > apply(x,2,max) #对每一列使用max()函数
  9. [1] "6" "World" "7000"
  10. > (y <- lapply(x,sort)) #对每列使用sort()函数
  11. [[1]]
  12. [1] 1 2 3 4 5 6
  13. [[2]]
  14. [1] "Hello" "Jack" "Ketty" "Rose" "Tom" "World"
  15. [[3]]
  16. [1] 2000 3000 4000 5000 6000 7000
  17. > (z <- sapply(x,sort))
  18. [,1] [,2] [,3]
  19. [1,] "1" "Hello" "2000"
  20. [2,] "2" "Jack" "3000"
  21. [3,] "3" "Ketty" "4000"
  22. [4,] "4" "Rose" "5000"
  23. [5,] "5" "Tom" "6000"
  24. [6,] "6" "World" "7000"
  25. >

数据框是列表的特例,数据框的列构成了列表的组件,所以也可以在数据框的每列上应用apply()函数和lapply()函数,包括sapply()函数


  1. > x
  2. id name salary
  3. 1 1 Tom 2000
  4. 2 2 Jack 3000
  5. 3 3 Rose 4000
  6. 4 4 Ketty 5000
  7. 5 5 Hello 6000
  8. 6 6 World 7000
  9. > y
  10. id
  11. 1 3
  12. 2 4
  13. 3 5
  14. 4 6
  15. 5 7
  16. 6 8
  17. > merge(x,y) #按照x和y中共有的字段的值相等来做合并
  18. id name salary
  19. 1 3 Rose 4000
  20. 2 4 Ketty 5000
  21. 3 5 Hello 6000
  22. 4 6 World 7000

在关系型数据库中经常会需要合并,即将两张表根据某个共同变量的值相等来组合到一起,join操作;在R中可以用 merge()来实现。比如上例,将x和y按照id字段的相等值合并

  1. > names(y) <- "old_id"
  2. > y
  3. old_id
  4. 1 3
  5. 2 4
  6. 3 5
  7. 4 6
  8. 5 7
  9. 6 8
  10. > merge(x,y)
  11. id name salary old_id
  12. 1 1 Tom 2000 3
  13. 2 2 Jack 3000 3
  14. 3 3 Rose 4000 3
  15. 4 4 Ketty 5000 3
  16. 5 5 Hello 6000 3
  17. 6 6 World 7000 3
  18. 7 1 Tom 2000 4
  19. 8 2 Jack 3000 4
  20. 9 3 Rose 4000 4
  21. 10 4 Ketty 5000 4
  22. 11 5 Hello 6000 4
  23. 12 6 World 7000 4
  24. 13 1 Tom 2000 5
  25. 14 2 Jack 3000 5
  26. 15 3 Rose 4000 5
  27. 16 4 Ketty 5000 5
  28. 17 5 Hello 6000 5
  29. 18 6 World 7000 5
  30. 19 1 Tom 2000 6
  31. 20 2 Jack 3000 6
  32. 21 3 Rose 4000 6
  33. 22 4 Ketty 5000 6
  34. 23 5 Hello 6000 6
  35. 24 6 World 7000 6
  36. 25 1 Tom 2000 7
  37. 26 2 Jack 3000 7
  38. 27 3 Rose 4000 7
  39. 28 4 Ketty 5000 7
  40. 29 5 Hello 6000 7
  41. 30 6 World 7000 7
  42. 31 1 Tom 2000 8
  43. 32 2 Jack 3000 8
  44. 33 3 Rose 4000 8
  45. 34 4 Ketty 5000 8
  46. 35 5 Hello 6000 8
  47. 36 6 World 7000 8
  48. > merge(x,y, by.x = "id", by.y = "old_id")
  49. id name salary
  50. 1 3 Rose 4000
  51. 2 4 Ketty 5000
  52. 3 5 Hello 6000
  53. 4 6 World 7000
  54. >

当merge()函数中没有共同的字段时,结果就是全连接操作,也就是两个表做笛卡尔积;如果想按指定的列的值相等做合并操作,可以设置by.xby.y参数


  1. > x
  2. id name salary
  3. 1 1 Tom 2000
  4. 2 2 Jack 3000
  5. 3 3 Rose 4000
  6. 4 4 Ketty 5000
  7. 5 5 Hello 6000
  8. 6 6 World 7000
  9. > x[3:4,3] <- NA
  10. > x #假设数据框中有缺失值存在
  11. id name salary
  12. 1 1 Tom 2000
  13. 2 2 Jack 3000
  14. 3 3 Rose NA
  15. 4 4 Ketty NA
  16. 5 5 Hello 6000
  17. 6 6 World 7000
  18. > complete.cases(x) #可以用该函数查看某行是否不存在缺失值
  19. [1] TRUE TRUE FALSE FALSE TRUE TRUE
  20. > (w <- x[complete.cases(x),]) #提取没有缺失值的行
  21. id name salary
  22. 1 1 Tom 2000
  23. 2 2 Jack 3000
  24. 5 5 Hello 6000
  25. 6 6 World 7000
  26. >

若假设数据框中存在缺失值,则可以用complete.cases()函数检查某行是否不存在缺失值,结果是一个boolean型向量,每个元素指示对应的行是否不存在缺失值;若存在,则对应行的值为FALSE,不存在则为TRUE;得到这个指示的索引向量后,便可以提取数据框中不存在缺失值的行

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注