前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据清洗与管理之dplyr、tidyr

数据清洗与管理之dplyr、tidyr

作者头像
1480
发布2019-06-20 11:58:32
1.8K0
发布2019-06-20 11:58:32
举报
文章被收录于专栏:数据分析1480

本期回顾

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 二维数组行列引用

代码语言:javascript
复制
> 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

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

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

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

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

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

代码语言:javascript
复制
> 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

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

代码语言:javascript
复制
> 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

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

代码语言:javascript
复制
> head(iris$Petal.Length,5)
[1] 1.4 1.4 1.3 1.5 1.4

1 创建新变量

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

代码语言:javascript
复制
> 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等返回值,确定编码的位置。

代码语言:javascript
复制
> 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

同一变量分层编码

代码语言:javascript
复制
> 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()函数重命名变量

代码语言:javascript
复制
> 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()

代码语言:javascript
复制
> 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包的下述五个函数用法【高级数据管理包】

代码语言:javascript
复制
# 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()

代码语言:javascript
复制
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()

代码语言:javascript
复制
arrange(mtcars_df, disp) #可对列名加 desc(disp)进行降序

5.3 选择: select()

代码语言:javascript
复制
> 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()

代码语言:javascript
复制
#取行
#取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()

代码语言:javascript
复制
#对数据框调用其它函数进行汇总操作
summarise(mtcars_df,mdisp = mean(disp, na.rm = TRUE))

5.6 分组: group_by()

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

代码语言:javascript
复制
#当对数据集通过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包的下述四个函数用法

代码语言:javascript
复制
#install.packages("tidyr") #安装tidyr包
library(tidyr)

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

类似excel透视表反向操作

代码语言:javascript
复制
#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()

类似excel透视表操作

代码语言:javascript
复制
#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()

代码语言:javascript
复制
#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()

代码语言:javascript
复制
#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参考鸿燕藏锋博客

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • R语言|第2讲:生成数据
  • R语言常用的数据输入与输出方法 | 第三讲
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档