R语言 数据的整理与清洗(第一篇)

《Cookbook for R》 Manipulating Data ~ General

Sorting 排序

1、vectors 向量

{r} 复制代码
# 先随机生成一组向量
v <- sample(101:110)

# 排序sort()
sort(v)
#>  [1] 101 102 103 104 105 106 107 108 109 110

# 反向排序
sort(v, decreasing=TRUE)
#>  [1] 110 109 108 107 106 105 104 103 102 101

2、data frames 数据框

要对一个或多个列上的数据帧进行排序,可以使用 plyr 包中的 arrange()

{r} 复制代码
# 生成一个数据框
df <- data.frame (id=1:4,
            weight=c(20,27,24,22),
            size=c("small", "large", "medium", "large"))
df

library(plyr)

# 按weight这一列排序
arrange(df, weight)       # 使用arrange函数
df[ order(df$weight), ]   # 使用R自带函数
#>   id weight   size
#> 1  1     20  small
#> 2  4     22  large
#> 3  3     24 medium
#> 4  2     27  large

# 按size排序,再按weight排序
arrange(df, size, weight)         
df[ order(df$size, df$weight), ] 
#>   id weight   size
#> 4  4     22  large
#> 2  2     27  large
#> 3  3     24 medium
#> 1  1     20  small


# 按所有列进行排序,列的顺序从左到右
df[ do.call(order, as.list(df)), ] 

Note:size这一列是因子,按因子水平的顺序排序;在这种情况下,级别是自动分配的(在创建数据框时),因此large是第一个,small是最后一个。

3、reverse sort 反向排序

排序的整体顺序可以用参数 decreasing=TRUE 颠倒

若要反转特定列的方向,该方法取决于数据类型:

  1. Numbers:在变量名前面加上 - ,例如 df[ order(-df$weight), ] ;
  2. Factors:转换为整数,并在变量名前面加上 - ,例如 df[ order(-xtfrm(df$size)), ] ;
  3. Characters: 没有一个简单的方法可以做到这一点。一种方法是先转换为因子,然后如上所述进行排序
{r} 复制代码
# 按weight这一列反向排序 
arrange(df, -weight)                      # 使用arrange函数
df[ order(df$weight, decreasing=TRUE), ]  # 使用R自带函数
df[ order(-df$weight), ]                  # 使用R自带函数
#>   id weight   size
#> 2  2     27  large
#> 3  3     24 medium
#> 4  4     22  large
#> 1  1     20  small


# 按 size (increasing), 然后按 weight (decreasing)
arrange(df, size, -weight)        
df[ order(df$size, -df$weight), ]  
#>   id weight   size
#> 2  2     27  large
#> 4  4     22  large
#> 3  3     24 medium
#> 1  1     20  small


# 按 size (decreasing), 然后按 weight (increasing)
# R自带函数 xtfrm() ,用于生成一个数字向量
arrange(df, -xtfrm(size), weight)         # Use arrange from plyr package
df[ order(-xtfrm(df$size), df$weight), ]  # Use built-in R functions
#>   id weight   size
#> 1  1     20  small
#> 3  3     24 medium
#> 4  4     22  large
#> 2  2     27  large

Randomizing order 随机化排序

当你想随机化排序时

{r} 复制代码
# 先创造一个向量
v <- 11:20

# 使向量随机化
v <- sample(v)

# 再创建一个数据框
data <- data.frame(label=letters[1:5], number=11:15)
data
#>   label number
#> 1     a     11
#> 2     b     12
#> 3     c     13
#> 4     d     14
#> 5     e     15

# 使数据框随机化
data <- data[sample(1:nrow(data)), ]
data
#>   label number
#> 5     e     15
#> 2     b     12
#> 4     d     14
#> 3     c     13
#> 1     a     11

要使随机化可重复,应该为随机数生成器设置种子

Converting between vector types 向量类型转换

在数字向量、字符向量和因子之间进行转换

从这个数字向量 n 开始:

{r} 复制代码
n <- 10:14
n
#> [1] 10 11 12 13 14

要将数字向量转换为其他两种类型:

{r} 复制代码
# Numeric 数字型 to Character 字符型
c <- as.character(n)

# Numeric 数字型 to Factor 因子型
f <- factor(n)
# 10 11 12 13 14

要将字符向量转换为其他两个:

{r} 复制代码
# Character 字符型 to Numeric 数字型
as.numeric(c)
#> [1] 10 11 12 13 14

# Character 字符型 to Factor 因子型
factor(c)
#> [1] 10 11 12 13 14
#> Levels: 10 11 12 13 14

将因子转换为字符向量很简单:

{r} 复制代码
# Factor to Character
as.character(f)
#> [1] "10" "11" "12" "13" "14"

但把因子转为数值型则有点棘手

如果你只是用 as.numeric 转换它,它会给你给予因子的数字编码,这可能不是你想要的结果

{r} 复制代码
as.numeric(f)
#> [1] 1 2 3 4 5

# 另一种得到数字编码的方式
unclass(f)
#> [1] 1 2 3 4 5
#> attr(,"levels")
#> [1] "10" "11" "12" "13" "14"

将文本内容转换为数字的方法是:

首先将其转换为字符,然后转换为数字向量

{r} 复制代码
# Factor to Numeric
as.numeric(as.character(f))
#> [1] 10 11 12 13 14

Finding and removing duplicate records 查找和删除重复记录

从向量或数据框中查找和/或删除重复条目

1、对向量

{r} 复制代码
# 设置随机种子
# 生成一个向量,取整数部分
set.seed(158)
x <- round(rnorm(20, 10, 5))
x
#>  [1] 14 11  8  4 12  5 10 10  3  3 11  6  0 16  8 10  8  5  6  6

# duplicate()判断是否有重复
# 某元素第一次出现的位置返回FALSE,第二次出现的位置返回TRUE
duplicated(x)
#>  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE
#> [15]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

# 利用返回的逻辑值取子集
x[duplicated(x)]
#> [1] 10  3 11  8 10  8  5  6  6
# 因为6、10、8出现了3次,后两次都是TRUE
# 所以会被选出来2个

# 用unique()去重复
# unique()默认保留第一次出现的元素
unique(x[duplicated(x)])
#> [1] 10  3 11  8  5  6

# 用unique()给原始x去重复
unique(x)
#>  [1] 14 11  8  4 12  5 10  3  6  0 16
# !逆转逻辑值
x[!duplicated(x)]
#>  [1] 14 11  8  4 12  5 10  3  6  0 16

2、对数据框

{r} 复制代码
# 示例
df <- read.table(header=TRUE, text='
 label value
     A     4
     B     3
     C     6
     B     3
     B     1
     A     2
     A     4
     A     4
')


# 判断是否有重复的行?
duplicated(df)
#> [1] FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE

# 找出重复的行
df[duplicated(df),]
#>   label value
#> 4     B     3
#> 7     A     4
#> 8     A     4

# 重复条目去重
unique(df[duplicated(df),])
#>   label value
#> 4     B     3
#> 7     A     4

# 原始数据去重复,返回去掉重复的数据框
unique(df)
#>   label value
#> 1     A     4
#> 2     B     3
#> 3     C     6
#> 5     B     1
#> 6     A     2
df[!duplicated(df),]
#>   label value
#> 1     A     4
#> 2     B     3
#> 3     C     6
#> 5     B     1
#> 6     A     2

Comparing vectors or factors with NA 将向量或因子与NA进行比较

想要比较两个向量或因子

但希望与 NA 比较的结果报告为 TRUEFALSE (而不是 NA

假如你有这样的数据框

由两列布尔向量(逻辑)组成,且内含 NA

{r} 复制代码
df <- data.frame( a=c(TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,NA,NA,NA),
                  b=c(TRUE,FALSE,NA,TRUE,FALSE,NA,TRUE,FALSE,NA))
df
#>       a     b
#> 1  TRUE  TRUE
#> 2  TRUE FALSE
#> 3  TRUE    NA
#> 4 FALSE  TRUE
#> 5 FALSE FALSE
#> 6 FALSE    NA
#> 7    NA  TRUE
#> 8    NA FALSE
#> 9    NA    NA

默认情况,当比较两个包含 NA 值的向量或因子时,

只要原始项中的任一项为 NA,结果向量将具有 NA

{r} 复制代码
# 两列相比,相同返回TRUE
df$a == df$b
#> [1]  TRUE FALSE    NA FALSE  TRUE    NA    NA    NA    NA

# 将结果新增一列到数据框中
data.frame(df, isSame = (df$a==df$b))
#>       a     b isSame
#> 1  TRUE  TRUE   TRUE
#> 2  TRUE FALSE  FALSE
#> 3  TRUE    NA     NA
#> 4 FALSE  TRUE  FALSE
#> 5 FALSE FALSE   TRUE
#> 6 FALSE    NA     NA
#> 7    NA  TRUE     NA
#> 8    NA FALSE     NA
#> 9    NA    NA     NA

NA 比较的函数:

这个函数本质上将 NA 视为另一个值。

如果两个向量中的一个项都是 NA ,则它报告该项的 TRUE ;

如果该项在一个向量中是 NA ,则它报告 FALSE ;

所有其他比较(非 NA 项之间)的行为相同。

{r} 复制代码
# 只要内容相同就返回TRUE
compareNA <- function(v1,v2) {
    same <- (v1 == v2) | (is.na(v1) & is.na(v2))
    same[is.na(same)] <- FALSE
    return(same)
}

应用该函数比较布尔向量

{r} 复制代码
compareNA(df$a, df$b)
#> [1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE

data.frame(df, isSame = compareNA(df$a,df$b))
#>       a     b isSame
#> 1  TRUE  TRUE   TRUE
#> 2  TRUE FALSE  FALSE
#> 3  TRUE    NA  FALSE
#> 4 FALSE  TRUE  FALSE
#> 5 FALSE FALSE   TRUE
#> 6 FALSE    NA  FALSE
#> 7    NA  TRUE  FALSE
#> 8    NA FALSE  FALSE
#> 9    NA    NA   TRUE

应用该函数比较因子

即使因子的水平顺序不同

{r} 复制代码
# 先创建两列因子
df1 <- data.frame(a = factor(c('x','x','x','y','y','y', NA, NA, NA)),
                  b = factor(c('x','y', NA,'x','y', NA,'x','y', NA)))

# 比较因子
data.frame(df1, isSame = compareNA(df1$a, df1$b))
#>      a    b isSame
#> 1    x    x   TRUE
#> 2    x    y  FALSE
#> 3    x <NA>  FALSE
#> 4    y    x  FALSE
#> 5    y    y   TRUE
#> 6    y <NA>  FALSE
#> 7 <NA>    x  FALSE
#> 8 <NA>    y  FALSE
#> 9 <NA> <NA>   TRUE


# 即便因子顺序被改变,也不影响比较结果
df1$b <- factor(df1$b, levels=c('y','x'))
data.frame(df1, isSame = compareNA(df1$a, df1$b))
#>      a    b isSame
#> 1    x    x   TRUE
#> 2    x    y  FALSE
#> 3    x <NA>  FALSE
#> 4    y    x  FALSE
#> 5    y    y   TRUE
#> 6    y <NA>  FALSE
#> 7 <NA>    x  FALSE
#> 8 <NA>    y  FALSE
#> 9 <NA> <NA>   TRUE
相关推荐
紫钺-高山仰止2 分钟前
【脑机接口】脑机接口性能的电压波形的尖峰分类和阈值比较
大数据·分类·数据挖掘
Galaxy.4047 分钟前
基于深度学习的文本情感原因提取研究综述——论文阅读
论文阅读·笔记
余生的观澜1 小时前
4.铝箔缺陷检测项目复盘
笔记
jason_renyu1 小时前
CICD简单描述笔记
笔记·cicd·cicd部署
晓幂1 小时前
CTFShow-信息搜集
笔记·学习
阡之尘埃3 小时前
Python数据分析案例59——基于图神经网络的反欺诈交易检测(GCN,GAT,GIN)
python·神经网络·数据挖掘·数据分析·图神经网络·反欺诈·风控大数据
小米里的大麦3 小时前
【C++】深入理解引用:从基础到进阶详解
c++·经验分享·笔记·引用·引用和指针
MowenPan19953 小时前
高等数学 3.5 函数的极值与最大值最小值
笔记·学习·高等数学
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑3 小时前
苍穹外卖学习笔记(七)
java·windows·笔记·学习·mybatis
环能jvav大师3 小时前
基于R语言的统计分析基础:使用dplyr包进行数据操作
大数据·开发语言·数据分析·r语言