首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >快速掌握R语言中类SQL数据库操作技巧

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

作者头像
1480
发布2019-09-25 16:29:46
5.6K0
发布2019-09-25 16:29:46
举报
文章被收录于专栏:数据分析1480数据分析1480

在数据分析中,往往会遇到各种复杂的数据处理操作:分组、排序、过滤、转置、填充、移动、合并、分裂、去重、找重、填充等操作。这时候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种类型是最常用的:向量、矩阵、数据框、时间序列。

可参考↓↓

R语言|第2讲:生成数据

R语言快速入门:数据结构+生成数据+数据引用+读取外部数据

  • 向量 Vector : c()
  • 矩阵 Matrix: matrix()
  • 数据框 DataFrame: data.frame()
  • 时间序列 XTS: xts()
  • 因子Factor:factor(补充)

(图片来自于粉丝日志)

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()

> 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/

2.查看数据概况
> 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个向量之间的数值的关系,找到包含关系、取交集、并集、差集等。、

# 定义2个向量x,y
> x<-c(3:8,NA);x
[1]  3  4  5  6  7  8 NA
> y<-c(NA,6:10,NA);y
[1] NA  6  7  8  9 10 NA

# 判断x与y重复的元素的位置
> is.element(x, y)
[1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE

# 判断y与x重复的元素的位置
> is.element(y, x)
[1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE

# 取并集
> union(x, y)
[1]  3  4  5  6  7  8 NA  9 10

# 取交集
> intersect(x, y)
[1]  6  7  8 NA

# 取x有,y没有元素
> setdiff(x, y)
[1] 3 4 5

# 取y有,x没有元素
> setdiff(y, x)
[1]  9 10

# 判断2个向量是否相等
> setequal(x, y)
[1] FALSE
数据连接主要涉及到merge函数和dplyr包中的*_join等函数,另外sqldf函数(SQL)亦可以实现数据连接功能。

参考→《R语言 数据(集)合并与连接/匹配 | 专题2》

4.过滤/筛选

过滤,是对数据集按照某种规则进行筛选,去掉不符合条件的数据,保留符合条件的数据。对于NA值的操作,主要都集中在了过滤操作和填充操作中,因此就不在单独介绍NA值的处理了。

可参考↓↓

R语言 | 第一部分:数据预处理 7.数据筛选和8.抽样

R语言数据管理与dplyr、tidyr | 第4讲 5 dplyr中5.1筛选filter和5.3选择select

R 语言 逻辑运算:TRUE/FALSE | 专题3

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 数值分段

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

> x<-1:10;x
 [1]  1  2  3  4  5  6  7  8  9 10

# 把向量转换为3段因子,分别列出每个值对应因子
> cut(x, 3)
 [1] (0.991,4] (0.991,4] (0.991,4] (0.991,4] (4,7]     (4,7]     (4,7]     (7,10]    (7,10]    (7,10]
Levels: (0.991,4] (4,7] (7,10]

# 对因子保留2位精度,并支持排序
> cut(x, 3, dig.lab = 2, ordered = TRUE)
 [1] (0.99,4] (0.99,4] (0.99,4] (0.99,4] (4,7]    (4,7]    (4,7]    (7,10]   (7,10]   (7,10]
Levels: (0.99,4] < (4,7] < (7,10]

5 分组操作

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

参考→《R语言 分组计算,不止group_by

  • 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()函数来生成索引,再匹配的数据的数值上面。

可参考↓↓

R语言 排序&去重操作 | 专题1

R语言 | 第一部分:数据预处理

> 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. 计数

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

# 生成20个随机数的向量
set.seed(1234)
x<-round(rnorm(20)*5);x
# 统计每个值出现的次数
table(x)
hist(x,xlim = c(-10,13),breaks=5)

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. 去重与找重

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

可参考↓↓

R语言 | 第一部分:数据预处理

R语言 排序&去重操作 | 专题1

R 语言 逻辑运算:TRUE/FALSE | 专题3

> x<-c(3:6,5:8);x
[1] 3 4 5 6 5 6 7 8

# 去掉重复元素
> unique(x)
[1] 3 4 5 6 7 8

# 找到重复元素,索引位置
> duplicated(x)
[1] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE

# 找到重复元素
> x[duplicated(x)]
[1] 5 6
10.转置

转置是一个数学名词,把行和列进行互换,一般用于对矩阵的操作。

# 创建一个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
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据分析1480 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开始之前,需要先了解一下R语言支持的数据类型,以及这些常用类型的特点。以下4种类型是最常用的:向量、矩阵、数据框、时间序列。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档