1、tidyr包的下述四个函数用法:
- 1)gather—宽数据转为长数据;
- 2)spread—长数据转为宽数据;
- 3)unit—多列合并为一列;
- 4)separate—将一列拆分为多列。
1.1 安装和载入tidyr包
install.packages("tidyr")
library(tidyr)
1.2 新建数据框用来演示
> a<-data.frame(GeneId = rep("gene5",times=3), #rep重复 gene5重复3次
+ SampleName =paste("Sample",1:3,sep=""),
#或者paste0("Sample",1:3)###paste连接两个字符串,分隔符是'''',无空格
+ Expression=c(14,19,18))
> a
GeneId SampleName Expression
1 gene5 Sample1 14
2 gene5 Sample2 19
3 gene5 Sample3 18
1.3 Tidy Data
R将清洁数据定义为:每个变量的数据存储在自身的列中,每个观测值的数据存储在其自身的行中。整洁数据是进行数据再加工的基础。
得到清洁数据,是为了实现
(1)数据框的变形
(2)数据框中的空值NA的补齐或删除
(3)长表与宽表的互换
(4)实现行或列的分割和合并
2.1 gather() 宽数据变长数据
gather(data,key="“,value=”",…, na.rm = FALSE) ## key是变量,value是值
gather的意义是重新塑造数据的变量,原有数据的变量并不是真正的变量
- gather的变量指定其中,- 表示除外某向量,其余全部gather
参数 | 参数名称 | 说明 |
---|---|---|
参数1 | data | 需要被转化的宽形表 |
参数2 | key变量名 | 将原数据框中的变量名赋值给一个新变量key="" |
参数3 | value变量名 | 将原数据框中的所有值赋给一个新变量value="" |
参数4 | … | 表示指定哪些列聚到同一列中 |
参数5 | na.rm | 是否删除缺失值 |
//创建一个新的数据框练习tidyr包
> geneid <- c("gene1","gene2","gene3","gene4")
> sample1 <- c(1,4,7,10)
> sample2 <- c(2,5,0.8,11)
> sample3 <- c(3,6,9,12)
> sample4 <- c(1,3,2,15)
> sample5 <- c(2,4,6,8)
> resach1 <- data.frame(geneid,sample1,sample2,sample3,sample4,sample5)
> resach1
geneid sample1 sample2 sample3 sample4 sample5
1 gene1 1 2.0 3 1 2
2 gene2 4 5.0 6 3 4
3 gene3 7 0.8 9 2 6
4 gene4 10 11.0 12 15 8
> library(tidyr)#之前操作的时候,出现报错
> newresearch <- resach1%>%gather(sample_nm,exp,sample1:sample5)
#%>%链式操作;%>%的功能是用于实现将一个函数的输出传递给下一个函数的第一个参数。
#注意这里的,传递给下一个函数的第一个参数,然后就不用写第一个参数了。
#tidyr很好的一点是可以只gather若干列而其他列保持不变。
> newresearch
geneid sample_nm exp
1 gene1 sample1 1.0
2 gene2 sample1 4.0
3 gene3 sample1 7.0
4 gene4 sample1 10.0
5 gene1 sample2 2.0
6 gene2 sample2 5.0
7 gene3 sample2 0.8
8 gene4 sample2 11.0
9 gene1 sample3 3.0
10 gene2 sample3 6.0
11 gene3 sample3 9.0
12 gene4 sample3 12.0
13 gene1 sample4 1.0
14 gene2 sample4 3.0
15 gene3 sample4 2.0
16 gene4 sample4 15.0
17 gene1 sample5 2.0
18 gene2 sample5 4.0
19 gene3 sample5 6.0
20 gene4 sample5 8.0
> unique(newresearch$sample_nm)#表示筛选出这类数据#unique去重复
[1] "sample1" "sample2" "sample3" "sample4" "sample5"
#gather()里面聚合列的表达式可以有多种变化,但输出的结果是一样的
#gather(key="sample_nm",value="exp",sample1,sample2,sample3,sample4,sample5)
#gather(key="sample_nm",value="exp",-geneid)
> newresearch2 <- resach1%>%gather(key="sample_nm",value="exp",sample1,sample3,sample5)#不连续选取
#还可以任意提取行数聚合,未聚合列的不变
> head(newresearch2)
geneid sample2 sample4 sample_nm exp
1 gene1 2.0 1 sample1 1
2 gene2 5.0 3 sample1 4
3 gene3 0.8 2 sample1 7
4 gene4 11.0 15 sample1 10
5 gene1 2.0 1 sample3 3
6 gene2 5.0 3 sample3 6
2.2 spread() 长数据变宽数据
spread(data, key, value, fill = NA, convert = FALSE, drop = TRUE)
data:为需要转换的长形表
key:需要将变量值拓展为字段的变量
value:需要分散的值
fill:对于缺失值,可将fill的值赋值给被转型后的缺失值
接上面
> nrspread <- newresearch%>%spread(sample_um,exp)#同样,管道数据直接传递给下一个函数的第一个参数。
> nrspread
geneid sample1 sample2 sample3 sample4 sample5
1 gene1 1 2.0 3 1 2
2 gene2 4 5.0 6 3 4
3 gene3 7 0.8 9 2 6
4 gene4 10 11.0 12 15 8
2.3 unite--多列合并为一列
unite(data, col, …, sep = “_”, remove = TRUE)
data:为数据框
col:被组合的新列名称
…:指定哪些列需要被组合
sep:组合列之间的连接符,默认为下划线
remove:是否删除被组合的列
#先构建一个数据框
> set.seed(1)
> date <- as.Date('2016-11-01') + 0:14
> hour <- sample(1:24, 15)
> min <- sample(1:60, 15)
> second <- sample(1:60, 15)
> event <- sample(letters, 15)
> data <- data.table(date, hour, min, second, event)
> data
date hour min second event
1: 2016-11-01 7 30 29 u
2: 2016-11-02 9 43 36 a
3: 2016-11-03 13 58 60 l
4: 2016-11-04 20 22 11 q
5: 2016-11-05 5 44 47 p
6: 2016-11-06 18 52 37 k
7: 2016-11-07 19 12 43 r
8: 2016-11-08 12 35 6 i
9: 2016-11-09 11 7 38 e
10: 2016-11-10 1 14 21 b
11: 2016-11-11 3 20 42 w
12: 2016-11-12 14 1 32 t
13: 2016-11-13 23 19 52 h
14: 2016-11-14 21 41 26 s
15: 2016-11-15 8 16 25 o
#将date和hour合并起来命名为datehour,用函数unite()
> datehournew <- data%>%unite(datehour,date,hour,sep = " ")
#也可以不用链式,unite(data,datehour,date,hour,sep = " ")
> datehournew
datehour min second event
1: 2016-11-01 7 30 29 u
2: 2016-11-02 9 43 36 a
3: 2016-11-03 13 58 60 l
4: 2016-11-04 20 22 11 q
5: 2016-11-05 5 44 47 p
6: 2016-11-06 18 52 37 k
7: 2016-11-07 19 12 43 r
8: 2016-11-08 12 35 6 i
9: 2016-11-09 11 7 38 e
10: 2016-11-10 1 14 21 b
11: 2016-11-11 3 20 42 w
12: 2016-11-12 14 1 32 t
13: 2016-11-13 23 19 52 h
14: 2016-11-14 21 41 26 s
15: 2016-11-15 8 16 25 o
#可以同时合并多个
>datehournew2 <- datehournew%>%unite(datetime,datehour,min,second,sep = ":")
> datehournew2
datatime event
1: 2016-11-01 7:30:29 u
2: 2016-11-02 9:43:36 a
3: 2016-11-03 13:58:60 l
4: 2016-11-04 20:22:11 q
5: 2016-11-05 5:44:47 p
6: 2016-11-06 18:52:37 k
7: 2016-11-07 19:12:43 r
8: 2016-11-08 12:35:6 i
9: 2016-11-09 11:7:38 e
10: 2016-11-10 1:14:21 b
11: 2016-11-11 3:20:42 w
12: 2016-11-12 14:1:32 t
13: 2016-11-13 23:19:52 h
14: 2016-11-14 21:41:26 s
15: 2016-11-15 8:16:25 o
2.4 separate--将一列分离为多列
一般可用于日志数据或日期时间型数据的拆分
separate(data, col, into, sep = “分隔符”, remove = TRUE,
convert = FALSE, extra = “warn”, fill = “warn”, …)
data:为数据框
col:需要被拆分的列
into:新建的列名,为字符串向量
sep:被拆分列的分隔符
remove:是否删除被分割的列
# 可以用separate函数将数据恢复到刚创建的时候
# 首先,将datetime分为date列和time列 然后,将time列分为hour,min,second列
> datasp <- datehournew2 %>%separate(datetime, c('date', 'time'), sep = ' ') %>%separate(time, c('hour', 'min', 'second'), sep = ':')
> datasp
date hour min second event
1: 2016-11-01 7 30 29 u
2: 2016-11-02 9 43 36 a
3: 2016-11-03 13 58 60 l
4: 2016-11-04 20 22 11 q
5: 2016-11-05 5 44 47 p
6: 2016-11-06 18 52 37 k
7: 2016-11-07 19 12 43 r
8: 2016-11-08 12 35 6 i
9: 2016-11-09 11 7 38 e
10: 2016-11-10 1 14 21 b
11: 2016-11-11 3 20 42 w
12: 2016-11-12 14 1 32 t
13: 2016-11-13 23 19 52 h
14: 2016-11-14 21 41 26 s
15: 2016-11-15 8 16 25 o