数据清洗与管理之dplyr、tidyr

本期回顾

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

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

R语言常用的数据输入与输出方法 | 第三讲


本期目录

0 二维数组行列引用

1 创建新变量

2 变量重新编码

3 变量重新命名

4 缺失值

5 dplyr包的下述五个函数用法

5.1 筛选: filter

5.2 排列: arrange

5.3 选择: select

5.4 变形: mutate

5.5 汇总: summarise

5.6 分组: group_by

6 tidyr包的下述四个函数用法

6.1 宽数据转为长数据:gather (excel透视表反向操作)

6.2 长数据转为宽数据:spread (excel透视表功能)

6.3 多列合并为一列:unit

6.4 将一列分离为多列:separat



正 文

先前已经讲过R语言生成测试数据、数据预处理和外部数据输入等内容,但这仅仅是第一步,我们还需要对数据集进行筛选、缺失值处理等操作,以便获得可以应用于建模或者可视化的数据集(变量)。接下来就以鸢尾花测试数据集进行进一步的数据管理和筛选操作。


0 二维数组行列引用

 
 
> data(iris)	
> head(iris,5) #显示前5行	
#  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


数据集管理中,首先必须懂“对指定维度数据的引用”

例如:引用第一行数据,引用第一列数据,引用第一行第一列的数据。

 
 
> data(iris) #鸢尾花数据集	
> dim(iris) #读取iris数据集的维度数值,以“行数 列数 ”形式展示	
[1] 150   5   	
#说明iris数据集是150 x 5的二维数组


smiley_63.png通过行列值引用:数据集[行值,列值]


如行值或列值仅1个数字,表示仅引用该行或列的数据

 
 
> iris[1,]  #引用第1行数据	
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species	
1          5.1         3.5          1.4         0.2  setosa	
	
	
> head(iris[,1],5) #引用第1列的数据,其中因数据过长,使用head()函数取前5个数字	
[1] 5.1 4.9 4.7 4.6 5.0


如行值或列值为组合数据,则表示引用组合行列交叉位置的数据

 
 
> iris[1:5,1:3]	
  Sepal.Length Sepal.Width Petal.Length	
1          5.1         3.5          1.4	
2          4.9         3.0          1.4	
3          4.7         3.2          1.3	
4          4.6         3.1          1.5	
5          5.0         3.6          1.4


smiley_63.png通过变量名引用(多用于二维数组中):数据集$变量名

 
 
> head(iris$Petal.Length,5)	
[1] 1.4 1.4 1.3 1.5 1.4



1 创建新变量


在R语言中,可以通过变量计算/分布函数等生成数据,并赋值给特定变量。

 
 
> x <- (iris$Sepal.Length+iris$Sepal.Width)/3	
> x	
  [1] 2.866667 2.633333 2.633333 2.566667 2.866667 3.100000 2.666667 2.800000	
  [9] 2.433333 2.666667 3.033333 2.733333 2.600000 2.433333 3.266667 3.366667	
 [17] 3.100000 2.866667 3.166667 2.966667 2.933333 2.933333 2.733333 2.800000	
 [25] 2.733333 2.666667 2.800000 2.900000 2.866667 2.633333 2.633333 2.933333	
 [33] 3.100000 3.233333 2.666667 2.733333 3.000000 2.833333 2.466667 2.833333	
 [41] 2.833333 2.266667 2.533333 2.833333 2.966667 2.600000 2.966667 2.600000	
 [49] 3.000000 2.766667 3.400000 3.200000 3.333333 2.600000 3.100000 2.833333	
 [57] 3.200000 2.433333 3.166667 2.633333 2.333333 2.966667 2.733333 3.000000	
 [65] 2.833333 3.266667 2.866667 2.833333 2.800000 2.700000 3.033333 2.966667	
 [73] 2.933333 2.966667 3.100000 3.200000 3.200000 3.233333 2.966667 2.766667	
 [81] 2.633333 2.633333 2.833333 2.900000 2.800000 3.133333 3.266667 2.866667	
 [89] 2.866667 2.666667 2.700000 3.033333 2.800000 2.433333 2.766667 2.900000	
 [97] 2.866667 3.033333 2.533333 2.833333 3.200000 2.833333 3.366667 3.066667	
[105] 3.166667 3.533333 2.466667 3.400000 3.066667 3.600000 3.233333 3.033333	
[113] 3.266667 2.733333 2.866667 3.200000 3.166667 3.833333 3.433333 2.733333	
[121] 3.366667 2.800000 3.500000 3.000000 3.333333 3.466667 3.000000 3.033333	
[129] 3.066667 3.400000 3.400000 3.900000 3.066667 3.033333 2.900000 3.566667	
[137] 3.233333 3.166667 3.000000 3.333333 3.266667 3.333333 2.833333 3.333333	
[145] 3.333333 3.233333 2.933333 3.166667 3.200000 2.966667

算术运算符

  • +(加)

  • -(减)

  • *(乘)

  • /(除)

  • ^或 **  (求幂)

  • x%%y   (求余)

  • x%/%y   (商,整数)




2 变量重新编码


可用于将连续数据编码为分组数据,或者替代异常值等

在R中重新编码数据常用逻辑运算符,通过TRUE/FALSE等返回值,确定编码的位置。

 
 
> df <- iris	
#将Petal.Length列等于1.4的位置重新编码为“”	
> df$Petal.Length[df$Petal.Length == 1.4] <- ""  	
> head(df,10)	
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species	
1           5.1         3.5                      0.2  setosa	
2           4.9         3.0                      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                      0.2  setosa	
6           5.4         3.9          1.7         0.4  setosa	
7           4.6         3.4                      0.3  setosa	
8           5.0         3.4          1.5         0.2  setosa	
9           4.4         2.9                      0.2  setosa	
10          4.9         3.1          1.5         0.1  setosa

同一变量分层编码

 
 
> df <- iris	
> head(df,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	
> df <- within(df,{	
+         Petal.Length[Petal.Length == 1.4] <- "一点四"	
+         Petal.Length[Petal.Length == 1.3] <- "一点三"	
+         Petal.Length[Petal.Length == 1.5] <- "一点五"})	
> head(df,10) #重新编码后输出结果	
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species	
1           5.1         3.5       一点四         0.2  setosa	
2           4.9         3.0       一点四         0.2  setosa	
3           4.7         3.2       一点三         0.2  setosa	
4           4.6         3.1       一点五         0.2  setosa	
5           5.0         3.6       一点四         0.2  setosa	
6           5.4         3.9          1.7         0.4  setosa	
7           4.6         3.4       一点四         0.3  setosa	
8           5.0         3.4       一点五         0.2  setosa	
9           4.4         2.9       一点四         0.2  setosa	
10          4.9         3.1       一点五         0.1  setosa



3 变量重新命名


通过names()函数重命名变量

 
 
> df <- iris	
> head(df,5)	
  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	
> names(df)[5] <- "testNAME"	
> head(df,5)	
  Sepal.Length Sepal.Width Petal.Length Petal.Width testNAME	
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



4 缺失值


针对数据集中的缺失值,可以通过重新编码处理,还可以直接删除缺失值/缺失值行

删除缺失值行:na.omit()

 
 
> df <- matrix(c(1:5,NA,7:10),nrow=5)	
> df	
     [,1] [,2]	
[1,]    1   NA	
[2,]    2    7	
[3,]    3    8	
[4,]    4    9	
[5,]    5   10	
> df <-na.omit(df)	
> df	
     [,1] [,2]	
[1,]    2    7	
[2,]    3    8	
[3,]    4    9	
[4,]    5   10	
attr(,"na.action")	
[1] 1	
attr(,"class")	
[1] "omit"



5 dplyr包的下述五个函数用法【高级数据管理包】


 
 
# install.packages("dplyr")	
library(dplyr)	
	
#使用datasets包中的mtcars数据集做演示,首先将过长的数据整理成友好的tbl_df数据:	
> mtcars_df = tbl_df(mtcars)	
> head(mtcars_df)	
# A tibble: 6 x 11	
    mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb	
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>	
1  21       6   160   110  3.9   2.62  16.5     0     1     4     4	
2  21       6   160   110  3.9   2.88  17.0     0     1     4     4	
3  22.8     4   108    93  3.85  2.32  18.6     1     1     4     1	
4  21.4     6   258   110  3.08  3.22  19.4     1     0     3     1	
5  18.7     8   360   175  3.15  3.44  17.0     0     0     3     2	
6  18.1     6   225   105  2.76  3.46  20.2     1     0     3     1


5.1 筛选: filter()

 
 
filter(mtcars_df,mpg==21,hp==110) #按给定的逻辑判断筛选出符合要求的子数据集	
# A tibble: 2 x 11	
    mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb	
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>	
1    21     6   160   110   3.9  2.62  16.5     0     1     4     4	
2    21     6   160   110   3.9  2.88  17.0     0     1     4     4


5.2 排列: arrange()

 
 
arrange(mtcars_df, disp) #可对列名加 desc(disp)进行降序



5.3 选择: select()

 
 
> select(mtcars_df, disp:wt) #用列名作参数来选择子数据集:	
# A tibble: 32 x 4	
    disp    hp  drat    wt	
   <dbl> <dbl> <dbl> <dbl>	
 1  160    110  3.9   2.62	
 2  160    110  3.9   2.88	
 3  108     93  3.85  2.32	
 4  258    110  3.08  3.22	
 5  360    175  3.15  3.44	
 6  225    105  2.76  3.46	
 7  360    245  3.21  3.57	
 8  147.    62  3.69  3.19	
 9  141.    95  3.92  3.15	
10  168.   123  3.92  3.44	
# ... with 22 more rows


5.4 变形: mutate()

 
 
#取行	
#取1:dim(mtcars_df)[1]行	
mutate(mtcars_df, NO = 1:dim(mtcars_df)[1]) 	
	
#数值重定义和赋值	
#将Ozone列取负数赋值给new,然后Temp列重新计算为(Temp - 32) / 1.8	
mutate(airquality, new = -Ozone, Temp = (Temp - 32) / 1.8) 


5.5 汇总: summarise()

 
 
#对数据框调用其它函数进行汇总操作	
summarise(mtcars_df,mdisp = mean(disp, na.rm = TRUE))


5.6 分组: group_by()

%>% 是管道函数,将左侧数据结果传递到右侧,作为右侧处理的原始数据

 
 
#当对数据集通过group_by()添加了分组信息后,mutate(),arrange() 和 summarise() 函数会自动对这些 tbl 类数据执行分组操作。	
cars <- group_by(mtcars_df, cyl)	
countcars <- summarise(cars, count = n()) # count = n()用来计算次数	
	
	
# %>%管道函数,把相应的数据直接引用为右侧源数据集	
countcars <- group_by(mtcars_df, cyl) %>% summarise(count = n()) 



6 tidyr包的下述四个函数用法



 
 
#install.packages("tidyr") #安装tidyr包	
library(tidyr)


6.1 宽数据转为长数据:gather()

smiley_0.png类似excel透视表反向操作

 
 
#gather(data, key, value, …, na.rm = FALSE, convert = FALSE)	
#data:需要被转换的宽形表	
#key:将原数据框中的所有列赋给一个新变量key	
#value:将原数据框中的所有值赋给一个新变量value	
#…:可以指定哪些列聚到同一列中	
#na.rm:是否删除缺失值	
	
widedata <- data.frame(person=c('Alex','Bob','Cathy'),grade=c(2,3,4),score=c(78,89,88))	
#widedata	
#  person grade score	
#1   Alex     2    78	
#2    Bob     3    89	
#3  Cathy     4    88	
	
longdata <- gather(widedata, variable, value,-grade)	
#longdata	
#  person variable value	
#1   Alex    grade     2	
#2    Bob    grade     3	
#3  Cathy    grade     4	
#4   Alex    score    78	
#5    Bob    score    89	
#6  Cathy    score    88


6.2 长数据转为宽数据:spread()

smiley_0.png类似excel透视表操作

 
 
#spread(data, key, value, fill = NA, convert = FALSE, drop = TRUE)	
#data:为需要转换的长形表	
#key:需要将变量值拓展为字段的变量	
#value:需要分散的值	
#fill:对于缺失值,可将fill的值赋值给被转型后的缺失值	
	
stocks <- data.frame(	
  time = as.Date('2009-01-01') + 0:9,	
  X = rnorm(10, 0, 1),	
  Y = rnorm(10, 0, 2),	
  Z = rnorm(10, 0, 4)	
)	
	
stocksm <- stocks %>% gather(stock, price, -time)	
	
#stocksm	
#         time stock      price	
#1  2009-01-01     X -1.6411394	
#2  2009-01-02     X -0.2144050	
#3  2009-01-03     X -1.0630161	
	
stocksm %>% spread(stock, price)	
#         time          X          Y          Z	
#1  2009-01-01 -1.6411394 -5.2254532  7.5666852	
#2  2009-01-02 -0.2144050  0.3570096  4.8142193	
#3  2009-01-03 -1.0630161 -1.3085735  7.3624203	
	
stocksm %>% spread(time, price)	


6.3 多列合并为一列:unit()

 
 
#unite(data, col, …, sep = “_”, remove = TRUE)	
#data:为数据框	
#col:被组合的新列名称	
#…:指定哪些列需要被组合	
#sep:组合列之间的连接符,默认为下划线	
#remove:是否删除被组合的列	
	
wideunite<-unite(widedata, col = information, person, grade, score, sep= "-")	
wideunite	
#  information	
#1   Alex-2-78	
#2    Bob-3-89	
#3  Cathy-4-88


6.4 将一列分离为多列:separate()

 
 
#separate()函数可将一列拆分为多列,一般可用于日志数据或日期时间型数据的拆分,语法如下:	
#separate(data, col, into, sep = “[^[:alnum:]]+”, remove = TRUE,	
#convert = FALSE, extra = “warn”, fill = “warn”, …)	
#data:为数据框	
#col:需要被拆分的列	
#into:新建的列名,为字符串向量	
#sep:被拆分列的分隔符	
#remove:是否删除被分割的列 	
	
widesep <- separate(wideunite, information,c("person","grade","score"), sep = "-")	
widesep	
#  person grade score	
#1   Alex     2    78	
#2    Bob     3    89	
#3  Cathy     4    88

dplyr和tidyr参考鸿燕藏锋博客

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值