快速掌握R语言中类SQL数据库操作技巧

在数据分析中,往往会遇到各种复杂的数据处理操作:分组、排序、过滤、转置、填充、移动、合并、分裂、去重、找重、填充等操作。这时候R语言就是一个很好的选择:R可以高效地、优雅地解决数据处理操作。(本章节为R语言入门第二部分总结篇:数据操作)

本章内容布局思路:思来想后,想到SQL查询的查询思路可以作为本章节的布局思路

  • 1.了解表结构/数据结构

  • 2.对表中的一些数据做出修改、替换、甚至生成新字段

  • 3.from:数据合并/连接

  • 4.where:条件筛选/过滤

  • 5.group:分组

  • 6.having和select:呈现不明显

  • 7.order:排序

  • 8.其他补充

目录
1. 初识R语言支持的数据类型

1.1 向量 Vector : c()

1.2 矩阵 Matrix: matrix()

1.3 数据框 DataFrame: data.frame()

1.4 时间序列 XTS: xts()

1.5 因子Factor:factor(补充)

2.查看数据概况

summary()和str()

3.修改/替换/重定义数据
4.数据合并

3.1 向量合并

3.2 cbind列合并(等长)

3.3 rbind行合并

3.4 merge

3.5 补充:集合操作

4.过滤/筛选

4.1 缺失值处理

4.2 数据增减

4.3 数值分段cut

5.分组操作

5.1 aggregate语法

5.2 aggregate分组计算

5.3 aggregate分组计算(formula形式)

6. 排序order
7. 计数table
8. 分裂split
9. 去重与找重unique
10.转置


1. 初识R语言支持的数据类型

开始之前,需要先了解一下R语言支持的数据类型,以及这些常用类型的特点。以下4种类型是最常用的:向量、矩阵、数据框、时间序列。

可参考↓↓


  • 向量 Vector : c()

  • 矩阵 Matrix: matrix()

  • 数据框 DataFrame: data.frame()

  • 时间序列 XTS: xts()

  • 因子Factor:factor(补充)

640?wx_fmt=png

(图片来自于粉丝日志)
1.1 向量 Vector : c()
> x <- c(1:10)	
> x	
 [1]  1  2  3  4  5  6  7  8  9 10
1.2 矩阵 Matrix: matrix()
#矩阵用法	
matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,dimnames = NULL) #表示生成1行,1列的一个矩阵,其中仅仅包含一个元素“NA”	

	
#---示例---#	
> matrix(c(1,2,3, 11,12,13), nrow = 2, ncol = 3, byrow = TRUE, dimnames = list(c("row1", "row2"), c("C.1", "C.2", "C.3")))	
     C.1 C.2 C.3	
row1   1   2   3	
row2  11  12  13	
#nrow = 2和ncol = 3 定义2x3的2行3列矩阵	
#byrow = TRUE 是控制矩阵中的数据c(1,2,3, 11,12,13)按照行的顺序排列,默认按照列排列	
#dimnames = list(c("row1", "row2"), c("C.1", "C.2", "C.3")) 定义矩阵行名和列名
1.3 数据框 DataFrame: data.frame()
#其中" <- "是赋值的意思,将向量c(11:15)赋值给对象x	
> x <- c(11:15)  	
> y <- c(1:5)	

	
 #将向量x和y合并存储到数据框中,并重命名为xf和yf	
> data.frame(xf = x, yf = y)	
   xf yf	
1  11  1	
2  12  2	
3  13  3	
4  14  4	
5  15  5
1.4 时间序列 XTS: xts()
640?wx_fmt=png
> library(xts)	
> x <- c(11:15) 	
> xts(x,order.by=as.Date('2019-09-14')+1:5)	
           [,1]	
2019-09-15   11	
2019-09-16   12	
2019-09-17   13	
2019-09-18   14	
2019-09-19   15
关于xts类型的详细介绍,请参考文章《可扩展的时间序列xts》http://blog.fens.me/r-xts/
#factor是numeric数值类型	
#factor(x = character(), levels, labels = levels,exclude = NA, ordered = is.ordered(x), nmax = NA)	
#注意:levels与labels的对应关系,其中levels发挥角标作用,与labels位置对应	

	
#例1	
> x <- c("Man", "Male", "Man","Lady","Female")	
> xf <- factor(x, levels = c("Male","Man" ,"Lady","Female"),labels = c("Male","Male","Female","Female"))	
> xf	
[1] Male   Male   Male   Female Female	
Levels: Male Female	

	
#例2:因子在一定程度上可以理解为分类变量	
> x <-rep(c("A","B"),5)	
> x_f <- factor(x);x_f	
 [1] A B A B A B A B A B	
Levels: A B	
> summary(x_f)	
A B 	
5 5 	
> str(x_f)	
 Factor w/ 2 levels "A","B": 1 2 1 2 1 2 1 2 1 2	
> sum(x_f)	
Error in Summary.factor(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), na.rm = FALSE) : 	
  ‘sum’ not meaningful for factors	
> 	
> xf <- factor(x,levels=c("A","B"),labels = c("1","2"));xf	
 [1] 1 2 1 2 1 2 1 2 1 2	
Levels: 1 2	
> summary(xf)	
1 2 	
5 5 	
> str(xf)	
 Factor w/ 2 levels "1","2": 1 2 1 2 1 2 1 2 1 2	
> sum(xf)	
Error in Summary.factor(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), na.rm = FALSE) : 	
  ‘sum’ not meaningful for factors
> data(iris)	
> head(iris,10)	
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species	
1           5.1         3.5          1.4         0.2  setosa	
2           4.9         3.0          1.4         0.2  setosa	
3           4.7         3.2          1.3         0.2  setosa	
4           4.6         3.1          1.5         0.2  setosa	
5           5.0         3.6          1.4         0.2  setosa	
6           5.4         3.9          1.7         0.4  setosa	
7           4.6         3.4          1.4         0.3  setosa	
8           5.0         3.4          1.5         0.2  setosa	
9           4.4         2.9          1.4         0.2  setosa	
10          4.9         3.1          1.5         0.1  setosa	

	

	
> summary(iris)	
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  	
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100   setosa    :50  	
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300   versicolor:50  	
 Median :5.800   Median :3.000   Median :4.350   Median :1.300   virginica :50  	
 Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199                  	
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800                  	
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500                  	

	

	
> str(iris)	
'data.frame':  150 obs. of  5 variables:	
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...	
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...	
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...	
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...	
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

3.修改/替换/重定义数据

修改指定单元格,修改指定列,within 关联修改

leadership$age[leadership$age==99] <- NA	
leadership$agecat2 <- NA	
leadership <- within(leadership,{ 	
agecat2[age>75] <- "Elder"	
  agecat2[age>=55 & age<=75] <- "Middle Aged"	
  agecat2[age<55] <- "Young"}	
)

4 数据合并

数据操作中,数据(集)合并是经常被用到。例如:合并来源不同,结构相似的两个表格
3.1 向量合并
#一维向量合并直接将要合并的变量以","分割放到c()中即可。	
> x <- c(11:20)	
> y <- c(1:10)	
> c(x,y)	
 [1] 11 12 13 14 15 16 17 18 19 20  1  2  3  4  5  6  7  8  9 10

3.2 cbind列合并(等长)

总结:cbind等行数、按列合并(无序)

#生成测试数据	
> ID1 <- c(1:4)	
> ID2 <- c(2:5)	
> name<-c("A","B","C","D")	
> score<-c(8,22,7,6)	
> student1<-data.frame(ID1,name)	
> student2<-data.frame(ID2,score)	

	
#按照行合并student1和student2	
> cbind(student1,student2)	
   ID1 name ID2 score1   	
1    A   2     82   	
2    B   3    223   	
3    C   4     74   	
4    D   5     6

3.3 rbind行合并

总结:按行合并,需要注意数据集需要有相同的列字段名

> #生成测试数据student1	
> ID <- c(1:4)	
> score <- c(8,22,7,33)	
> student1<-data.frame(ID,score)> 	

	
#生成测试数据student2	
> ID <- c("A","B","C","D")	
> score <- c(11,2,55,3)	
> student2<-data.frame(ID,score)	

	
#按行合并,需要注意数据集需要有相同的列字段名	
> rbind(student1,student2)	
ID score1  	
1     82  	
2    223  	
3     74  	
4    335  	
A    116  	
B     27  	
C    558  	
D     3

3.4 merge
#merge语法结构	
merge(x, y, by = intersect(names(x), names(y)),	
      by.x = by, by.y = by, all = FALSE, all.x = all, all.y = all,	
      sort = TRUE, suffixes = c(".x",".y"), no.dups = TRUE,	
      incomparables = NULL, ...)	
#其中,通过by字段控制连接字段by = "ID"为单字段连接,by = c("ID","NAME",……)为多字段连接;	
#通过all=FALSE/TRUE、all.x = TRUE和all.y = TRUE实现内连接、外连接、左连接和右连接

#———merge用法———#	
> #生成测试数据	
> ID1 <- c(1:4)	
> ID2 <- c(2:5)	
> name<-c("A","B","C","D")	
> score<-c(8,22,7,6)	
> student1<-data.frame(ID1,name)	
> student2<-data.frame(ID2,score)	
> 	
> #内连接:保留交叉位置数据	
> merge(student1,student2,by.x = "ID1", by.y = "ID2",all=TRUE)	
  ID1 name score	
1   1    A    NA	
2   2    B     8	
3   3    C    22	
4   4    D     7	
5   5 <NA>     6	
> #左连接:保留左边所有数据及交叉y数据	
> merge(student1,student2,by.x = "ID1", by.y = "ID2",all.x=TRUE)	
  ID1 name score	
1   1    A    NA	
2   2    B     8	
3   3    C    22	
4   4    D     7	
> #右连接:保留右边所有数据及交叉x数据	
> merge(student1,student2,by.x = "ID1", by.y = "ID2",all.y=TRUE)	
  ID1 name score	
1   2    B     8	
2   3    C    22	
3   4    D     7	
4   5 <NA>     6
3.5 补充:集合操作
集合操作,是对2个向量的操作,处理2个向量之间的数值的关系,找到包含关系、取交集、并集、差集等。、
 
 

4.过滤/筛选

过滤,是对数据集按照某种规则进行筛选,去掉不符合条件的数据,保留符合条件的数据。对于NA值的操作,主要都集中在了过滤操作和填充操作中,因此就不在单独介绍NA值的处理了。
可参考↓↓
    7.数据筛选和8.抽样
    5 dplyr中5.1筛选filter和5.3选择select

4.1 缺失值处理
# 生成数据框	
> df<-data.frame(a=c(1,NA,NA,2,NA),	
+     b=c('B','A','B','B',NA),	
+     c=c(rnorm(2),NA,NA,NA));df	
   a    b          c	
1  1    B -0.3041839	
2 NA    A  0.3700188	
3 NA    B         NA	
4  2    B         NA	
5 NA <NA>         NA	

	
# 过滤有NA行的数据	
> na.omit(df)	
  a b          c	
1 1 B -0.3041839	

	
# 过滤,保留b列值为B的数据	
> df[which(df$b=='B'),]	
   a b          c	
1  1 B -0.3041839	
3 NA B         NA	
4  2 B         NA

4.2 数据增减

常见如以下不同方法

#方法一:减行数或列数	
x=x[,-1] #代表删除x数据集中第一列数据	

	
#方法二:dplyr::mutate#数值重定义和赋值	
#将Ozone列取负数赋值给new,然后Temp列重新计算为(Temp - 32) / 1.8	
mutate(airquality, new = -Ozone, Temp = (Temp - 32) / 1.8)	

	
#方法三:subset筛选变量服从某值的子集	
subset(airquality, Temp > 80, select = c(Ozone, Temp))

4.3 数值分段
数值分段,就是把一个连续型的数值型数据,按区间分割为因子类型的离散型数据。
 
 

5 分组操作

此处仅讲述aggregate数据分组计算内容,更多分组计算内容

参考→《》

  • dplyr包中的group_by联合summarize

  • group_by和summarise单变量分组计算

  • group_by和summarise多变量分组计算

  • ddply分组计算示例

5.1 aggregate语法

aggregate(x, by, FUN)	
#x为数据集	
#by为分组变量列表	
#FUN为计算函数

5.2 aggregate分组计算

> row_names <- rep(c("A","B","C"),3)	
> col_names <- LETTERS[1:3]	
> df_matrix <- matrix(c(1:27),nrow = 9,dimnames = list(row_names,col_names))	
> df_matrix	
  A  B  C	
A 1 10 19	
B 2 11 20	
C 3 12 21	
A 4 13 22	
B 5 14 23	
C 6 15 24	
A 7 16 25	
B 8 17 26	
C 9 18 27	

	
#注意分组变量为列表形式	
> aggregate(df_matrix,list(Group = row_names), mean)	
  Group A  B  C	
1     A 4 13 22	
2     B 5 14 23	
3     C 6 15 24

5.3 aggregate分组计算补充(formula形式)

可以重点了解一下

aggregate(formula, data, FUN)	
#Formulas, one ~ one, one ~ many, many ~ one, and many ~ many:	

	
#一组对一计算变量函数型分组计算:计算变量~分组变量	
> aggregate(weight ~ feed, data = chickwts, mean)	
       feed   weight	
1    casein 323.5833	
2 horsebean 160.2000	
3   linseed 218.7500	
4  meatmeal 276.9091	
5   soybean 246.4286	
6 sunflower 328.9167	

	
#多组对一函数型分组计算:计算变量~分组变量1+分组变量2……	
> aggregate(breaks ~ wool + tension, data = warpbreaks, mean)	
  wool tension   breaks	
1    A       L 44.55556	
2    B       L 28.22222	
3    A       M 24.00000	
4    B       M 28.77778	
5    A       H 24.55556	
6    B       H 18.77778	

	
#一组对多计算变量,函数型分组计算:cbind(计算变量1,计算变量2)~分组变量1	
> aggregate(cbind(Ozone, Temp) ~ Month, data = airquality, mean)	
  Month    Ozone     Temp	
1     5 23.61538 66.73077	
2     6 29.44444 78.22222	
3     7 59.11538 83.88462	
4     8 59.96154 83.96154	
5     9 31.44828 76.89655	

	
#多组对多计算变量,函数型分组计算:cbind(计算变量1,计算变量2)~分组变量1+分组变量2……	
> aggregate(cbind(ncases, ncontrols) ~ alcgp + tobgp, data = esoph, sum)	
       alcgp    tobgp ncases ncontrols	
1  0-39g/day 0-9g/day      9       261	
2      40-79 0-9g/day     34       179	
3     80-119 0-9g/day     19        61	
4       120+ 0-9g/day     16        24	
5  0-39g/day    10-19     10        84	
6      40-79    10-19     17        85	
7     80-119    10-19     19        49	
8       120+    10-19     12        18	
9  0-39g/day    20-29      5        42	
10     40-79    20-29     15        62	
11    80-119    20-29      6        16	
12      120+    20-29      7        12	
13 0-39g/day      30+      5        28	
14     40-79      30+      9        29	
15    80-119      30+      7        12	
16      120+      30+     10        13

6. 排序

#order默认升序,变量前加“-”代表降序
#排序的操作,大多都是基于索引来完成的
#用order()函数来生成索引,再匹配的数据的数值上面。
可参考↓↓


> row_names <- rep(c("A","B","C"),3)	
> col_names <- LETTERS[1:3]	
> set.seed(1234)	
> df_matrix <- matrix(round(rnorm(27,0,1),3),nrow = 9,dimnames = list(NULL,col_names));df_matrix	
           A      B      C	
 [1,] -1.207 -0.890 -0.837	
 [2,]  0.277 -0.477  2.416	
 [3,]  1.084 -0.998  0.134	
 [4,] -2.346 -0.776 -0.491	
 [5,]  0.429  0.064 -0.441	
 [6,]  0.506  0.959  0.460	
 [7,] -0.575 -0.110 -0.694	
 [8,] -0.547 -0.511 -1.448	
 [9,] -0.564 -0.911  0.575	
> df_frame <-   data.frame(group=row_names,df_matrix);df_frame	
  group      A      B      C	
1     A -1.207 -0.890 -0.837	
2     B  0.277 -0.477  2.416	
3     C  1.084 -0.998  0.134	
4     A -2.346 -0.776 -0.491	
5     B  0.429  0.064 -0.441	
6     C  0.506  0.959  0.460	
7     A -0.575 -0.110 -0.694	
8     B -0.547 -0.511 -1.448	
9     C -0.564 -0.911  0.575	
> 	
> #order,其中默认升序,变量前加“-”代表降序	
> #排序的操作,大多都是基于索引来完成的	
> #用order()函数来生成索引,再匹配的数据的数值上面。	
> df_frame[order(df_frame$A),]	
  group      A      B      C	
4     A -2.346 -0.776 -0.491	
1     A -1.207 -0.890 -0.837	
7     A -0.575 -0.110 -0.694	
9     C -0.564 -0.911  0.575	
8     B -0.547 -0.511 -1.448	
2     B  0.277 -0.477  2.416	
5     B  0.429  0.064 -0.441	
6     C  0.506  0.959  0.460	
3     C  1.084 -0.998  0.134	
> df_frame[order(df_frame$group,-df_frame$A),]	
  group      A      B      C	
7     A -0.575 -0.110 -0.694	
1     A -1.207 -0.890 -0.837	
4     A -2.346 -0.776 -0.491	
5     B  0.429  0.064 -0.441	
2     B  0.277 -0.477  2.416	
8     B -0.547 -0.511 -1.448	
3     C  1.084 -0.998  0.134	
6     C  0.506  0.959  0.460	
9     C -0.564 -0.911  0.575

7. 计数

计数,是统计同一个值出现的次数。

 
 

8 数据分裂

分裂计算,是把一个向量按照一列规则,拆分成多个向量的操作。有时候分裂split也被用于分组计算中。

> row_names <- rep(c("A","B","C"),3)	
> col_names <- LETTERS[1:3]	
> df_matrix <- matrix(c(1:27),nrow = 9,dimnames = list(NULL,col_names))	
> row_names <- rep(c("A","B","C"),3)	
> col_names <- LETTERS[1:3]	
> df_matrix <- matrix(c(1:27),nrow = 9,dimnames = list(NULL,col_names));df_matrix	
      A  B  C	
 [1,] 1 10 19	
 [2,] 2 11 20	
 [3,] 3 12 21	
 [4,] 4 13 22	
 [5,] 5 14 23	
 [6,] 6 15 24	
 [7,] 7 16 25	
 [8,] 8 17 26	
 [9,] 9 18 27	
> df_frame <-   data.frame(group=row_names,df_matrix);df_frame	
  group A  B  C	
1     A 1 10 19	
2     B 2 11 20	
3     C 3 12 21	
4     A 4 13 22	
5     B 5 14 23	
6     C 6 15 24	
7     A 7 16 25	
8     B 8 17 26	
9     C 9 18 27	
> df_split <- split(df_frame,row_names);df_split	
$A	
  group A  B  C	
1     A 1 10 19	
4     A 4 13 22	
7     A 7 16 25	

	
$B	
  group A  B  C	
2     B 2 11 20	
5     B 5 14 23	
8     B 8 17 26	

	
$C	
  group A  B  C	
3     C 3 12 21	
6     C 6 15 24	
9     C 9 18 27

另外,可以用因子类型来控制分裂。分成2步操作,第一步先分成与数据集同样长度的因子,第二步进行分裂,可以把一个大的向量拆分成多个小的向量。

> # 生成因子规则	
> n <- 3; size <- 5	
> fat <- factor(round(n * runif(n * size)));fat	
 [1] 3 3 1 1 0 1 2 1 3 3 1 1 2 2 2	
Levels: 0 1 2 3	
> # 生成数据向量	
> x <- rnorm(n * size);x	
 [1] -1.2107366 -1.3102467 -0.4083354 -0.5629753  1.2139442  1.6288760 -0.3160227 -1.8076242 -0.6125961	
[10] -2.1066644  1.2053009  1.3294407 -0.6836288 -1.7868047  0.1364916	
> # 对向量以因子的规则进行拆分	
> split(x, fat)	
$`0`	
[1] 1.213944	

	
$`1`	
[1] -0.4083354 -0.5629753  1.6288760 -1.8076242  1.2053009  1.3294407	

	
$`2`	
[1] -0.3160227 -0.6836288 -1.7868047  0.1364916	

	
$`3`	
[1] -1.2107366 -1.3102467 -0.6125961 -2.1066644

9. 去重与找重

去重,是把向量中重复的元素过滤掉。找重,是把向量中重复的元素找出来。
可参考↓↓


 
 
转置是一个数学名词,把行和列进行互换,一般用于对矩阵的操作。
# 创建一个3行5列的矩阵	
> m<-matrix(1:15,ncol=5);m	
     [,1] [,2] [,3] [,4] [,5]	
[1,]    1    4    7   10   13	
[2,]    2    5    8   11   14	
[3,]    3    6    9   12   15	

	
# 转置后,变成5行3列的矩阵	
> t(m)	
     [,1] [,2] [,3]	
[1,]    1    2    3	
[2,]    4    5    6	
[3,]    7    8    9	
[4,]   10   11   12	
[5,]   13   14   15
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值