R语言 数据混合
数据混合是将数据从不可用或错误的形式转化为有用的形式的一般技术。如果没有几度的数据清洗(不管是专门的用户还是自动系统执行),数据就不能为下游的消费做好准备。基本上,手动清理数据的程序被称为数据清洗。在R编程中,以下方法是面向数据清洗过程的。
- apply() 家庭
- aggregate()
- dplyr 包
- plyr 包
使用apply()系列进行数据混合
在R的 apply() 集合中,最基本的函数是 apply() 函数。除此之外,还有 lapply() 、 sapply() 和 tapply()。 apply() 的整个集合可以被认为是一个循环的替代品。它是限制性最强的函数类型。它应该在一个包含所有同质元素的矩阵上执行。如果 apply() 函数是用一个数据框架或任何其他类型的对象执行的,该函数将首先把它变成一个矩阵,然后再执行其操作。它基本上是用来避免明确使用循环结构或构造的。
语法
apply(X, margin, function)
参数
x: 一个数组或矩阵
margin: 一个介于1和2之间的值,用于决定在哪里应用函数 [ 1-行;2-列]
函数: 要应用的函数
例子
# Using apply()
m <- matrix(C <- (1:10),
nrow = 5,
ncol = 6)
m
a_m <- apply(m, 2, sum)
a_m
输出
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 6 1 6 1 6
[2,] 2 7 2 7 2 7
[3,] 3 8 3 8 3 8
[4,] 4 9 4 9 4 9
[5,] 5 10 5 10 5 10
[1] 15 40 15 40 15 40
在上面的例子中,我们是按列计算元素的总和。因此,对于一个大的数据集,我们可以很容易地产生期望的输出。
lapply() 函数用于对一个列表进行操作,它返回一个与输入列表相同大小的结果列表。 lapply() 中的’l’指的是列表。 lapply() 函数不需要 margin 参数。
语法
lapply(X, func)
参数
X: 列表或一个向量或一个对象
func: 要应用的函数
例子
# Using lapply()
movies <- c("SPIDERMAN", "BATMAN",
"AVENGERS", "FROZEN")
movies
movies_lower <- lapply(movies,
tolower)
str(movies_lower)
输出
[1] "SPIDERMAN" "BATMAN" "AVENGERS" "FROZEN"
List of 4
: chr "spiderman" : chr "batman"
: chr "avengers" : chr "frozen"
sapply() 函数接收任何向量或对象或列表,并执行与 lapply() 函数相同的操作。两者的语法相同。
tapply() 函数用于计算或测量平均值、中位数、最大值等,或对变量的每一个因子执行一个函数。它可以有效地用于创建任何向量的子集,然后对它们应用或执行任何函数。
语法
tapply(X, index, func = NULL)
参数
X: 一个对象或向量
index: 一个因子列表
func: 要应用的函数
例子
# Using tapply()
data(iris)
tapply(irisSepal.Width,
irisSpecies,
median)
输出
setosa versicolor virginica
3.4 2.8 3.0
在数据整合中使用聚合()函数
在R语言中, aggregate() 函数用于通过对子数据框的每一列应用一个函数来合并或聚合输入的数据框。为了进行聚合或应用 aggregate() 函数,我们必须包括以下内容。
- 我们希望聚合的输入数据
- 数据中用于分组的变量
- 要应用的函数或计算
aggregate() 函数总是会返回一个数据框,其中包含应用特定函数后输入数据框的所有唯一值。我们只能在一个聚合函数中应用一个单一的函数。为了在聚合() 函数中包含多个函数,我们需要使用 plyr 包。
语法
aggreg(formula, data, function)
参数
formula: 我们要应用函数的输入数据框的变量。
data: 我们希望用于分组操作的数据。
function: 要应用的函数或计算。
例子
# R program to illustrate
# aggregate() function
assets <- data.frame(
asset.class = c("equity", "equity",
"equity", "option",
"option", "option",
"bond", "bond"),
rating = c("AAA", "A", "A",
"AAA", "BB", "BB",
"AAA", "A"),
counterparty.a = c(runif(3), rnorm(5)),
counterparty.b = c(runif(3), rnorm(5)),
counterparty.c = c(runif(3), rnorm(5)))
assets
exposures <- aggregate(
x = assets[c("counterparty.a",
"counterparty.b",
"counterparty.c")],
by = assets[c("asset.class", "rating")],
FUN = function(market.values){
sum(pmax(market.values, 0))
})
exposures
输出
asset.class rating counterparty.a counterparty.b counterparty.c
1 equity AAA 0.08250275 0.5474595 0.9966172
2 equity A 0.33931258 0.6442402 0.2348197
3 equity A 0.68078755 0.5962635 0.6126720
4 option AAA -0.47624689 -0.4622881 -1.2362731
5 option BB -0.78860284 0.3219559 -1.2847157
6 option BB -0.59461727 -0.2840014 -0.5739735
7 bond AAA 1.65090747 1.0918564 0.6179858
8 bond A -0.05402813 0.1602164 1.1098481
asset.class rating counterparty.a counterparty.b counterparty.c
1 bond A 0.00000000 0.1602164 1.1098481
2 equity A 1.02010013 1.2405038 0.8474916
3 bond AAA 1.65090747 1.0918564 0.6179858
4 equity AAA 0.08250275 0.5474595 0.9966172
5 option AAA 0.00000000 0.0000000 0.0000000
6 option BB 0.00000000 0.3219559 0.0000000
我们可以看到,在上面的例子中,资产数据框架的值已经在 “asset.class “和 “rating “列上进行了聚合。
使用plyr包进行数据整合
plyr包 用于拆分、应用和组合数据。 plyr 是一套工具,可以用来分割巨大的或大的数据,以创建一个同质的片段,然后在每一个片段上应用一个函数,最后将所有的结果值合并。我们已经可以在R中进行这些操作了,但在使用 plyr 时,我们可以很容易地做到这一点。
- 名称、参数和输出是完全一致的
- 方便的并行性
- 输入和输出都涉及数据框、矩阵或列表
- 为了跟踪长期执行或运行的程序,它提供了一个进度条
- 内置信息丰富的错误信息和错误恢复
- 在所有的转换中都保持的标签。
本节中我们要讨论的两个函数是 ddply() 和 lply()。 对于一个给定的数据框架的每个子集, ddply() 应用一个函数,然后将其结果合并。
语法
ddply(.data, .variables, .fun = NULL, …, .progress = “none”, .inform = FALSE,
.drop = TRUE, .parallel = FALSE, .paropts = NULL)
参数
data: 要处理的数据框
variables: 分割数据框所依据的变量
fun: 要应用的函数
...:传递给函数的其他参数
progress: 进度条的名称
inform: 是否产生任何信息性的错误消息
drop: 不在输入数据框中的变量组合应被保留或放弃。
parallel: 是否应用平行函数
paropts: 传递的额外或附加选项的列表。
例子
# Using ddply()
library(plyr)
dfx <- data.frame(
group = c(rep('A', 8),
rep('B', 15),
rep('C', 6)),
sex = sample(c("M", "F"),
size = 29,
replace = TRUE),
age = runif(n = 29,
min = 18,
max = 54)
)
ddply(dfx, .(group, sex), summarize,
mean = round(mean(age), 2),
sd = round(sd(age), 2))
输出
group sex mean sd
1 A F 41.00 9.19
2 A M 35.76 12.14
3 B F 34.75 11.70
4 B M 40.01 10.10
5 C F 25.13 10.37
6 C M 43.26 7.63
现在我们将看到如何使用 llply() 来进行数据合并的工作。 llply() 函数用在列表的每个元素上,我们在其中应用一个函数,合并后的结果输出也是一个列表。
语法
llply(.data, .fun = NULL,
…, .progress = “none”, .inform = FALSE,
.paropts = FALSE)
例子
# Using llply()
library(plyr)
x <- list(a = 1:10, beta = exp(-3:3),
logic = c(TRUE, FALSE,
FALSE, TRUE))
llply(x, mean)
llply(x, quantile, probs = 1:3 / 4)
输出
$a
[1] 5.5
$beta
[1] 4.535125
$logic
[1] 0.5
$a
25% 50% 75%
3.25 5.50 7.75
$beta
25% 50% 75%
0.2516074 1.0000000 5.0536690
$logic
25% 50% 75%
0.0 0.5 1.0
使用dplyr包进行数据处理
dplyr包 可以被看作是数据处理的语法,它为我们提供了一套一致的动词,帮助我们解决一些最常见的数据处理的挑战。
- arrange() 是用来改变行的顺序的。
- filter() 用于根据其值或基于值来挑选案例。
- mutate() 用于添加新的变量,这些变量是已经存在的变量的函数。
- select() 用于根据变量的名称来挑选或选择变量。
- summarize() 用来将多个值减少到一个单一的摘要。
dplyr 下还有很多函数 。 dplyr 使用了一个非常高效的后台,这使得计算的等待时间更短。它比 plyr 包的效率更高。
语法
arrange(.data, ..., .by_group = FALSE)
filter(.data, ...)
mutate(.data, ...)
select(.data, ...)
summarize(X, by, fun, ..., stat.name = deparse(substitution(X))。
type = c(“variable”,”matrix”), subset = TRUE, keepcolnames = FALSE)
例子
# Using dplyr package
# Import the library
library(dplyr)
# Using arrange()
starwars %>%
arrange(desc(mass))
# Using filter()
starwars %>%
filter(species == "Droid")
# Using mutate()
starwars %>%
mutate(name,
bmi = mass / ((height / 100) ^ 2)) %>%
select(name:mass, bmi)
# Using select()
starwars %>%
select(name, ends_with("color"))
# Using summarise()
starwars %>% group_by(species) %>%
summarise(n = n(),
mass = mean(mass, na.rm = TRUE)) %>%
filter(n > 1)
输出
> starwars %>% arrange(desc(mass))
# A tibble: 87 x 13
name height mass hair_color skin_color eye_color birth_year gender homeworld species films vehicles starships
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr> <chr> <lis> <list> <list>
1 Jabba D~ 175 1358 NA green-tan, ~ orange 600 hermap~ Nal Hutta Hutt <chr~ <chr [0~ <chr [0]>
2 Grievous 216 159 none brown, white green, ye~ NA male Kalee Kaleesh <chr~ <chr [1~ <chr [1]>
3 IG-88 200 140 none metal red 15 none NA Droid <chr~ <chr [0~ <chr [0]>
4 Darth V~ 202 136 none white yellow 41.9 male Tatooine Human <chr~ <chr [0~ <chr [1]>
5 Tarfful 234 136 brown brown blue NA male Kashyyyk Wookiee <chr~ <chr [0~ <chr [0]>
6 Owen La~ 178 120 brown, grey light blue 52 male Tatooine Human <chr~ <chr [0~ <chr [0]>
7 Bossk 190 113 none green red 53 male Trandosha Trando~ <chr~ <chr [0~ <chr [0]>
8 Chewbac~ 228 112 brown unknown blue 200 male Kashyyyk Wookiee <chr~ <chr [1~ <chr [2]>
9 Jek Ton~ 180 110 brown fair blue NA male Bestine ~ Human <chr~ <chr [0~ <chr [1]>
10 Dexter ~ 198 102 none brown yellow NA male Ojom Besali~ <chr~ <chr [0~ <chr [0]>
# ... with 77 more rows
> starwars %>% filter(species == "Droid")
# A tibble: 5 x 13
name height mass hair_color skin_color eye_color birth_year gender homeworld species films vehicles starships
<chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr> <chr> <list> <list> <list>
1 C-3PO 167 75 NA gold yellow 112 NA Tatooine Droid <chr [6]> <chr [0]> <chr [0]>
2 R2-D2 96 32 NA white, blue red 33 NA Naboo Droid <chr [7]> <chr [0]> <chr [0]>
3 R5-D4 97 32 NA white, red red NA NA Tatooine Droid <chr [1]> <chr [0]> <chr [0]>
4 IG-88 200 140 none metal red 15 none NA Droid <chr [1]> <chr [0]> <chr [0]>
5 BB8 NA NA none none black NA none NA Droid <chr [1]> <chr [0]> <chr [0]>
> starwars %>% mutate(name, bmi = mass / ((height / 100) ^ 2)) %>% select(name:mass, bmi)
# A tibble: 87 x 4
name height mass bmi
<chr> <int> <dbl> <dbl>
1 Luke Skywalker 172 77 26.0
2 C-3PO 167 75 26.9
3 R2-D2 96 32 34.7
4 Darth Vader 202 136 33.3
5 Leia Organa 150 49 21.8
6 Owen Lars 178 120 37.9
7 Beru Whitesun lars 165 75 27.5
8 R5-D4 97 32 34.0
9 Biggs Darklighter 183 84 25.1
10 Obi-Wan Kenobi 182 77 23.2
# ... with 77 more rows
> starwars %>% select(name, ends_with("color"))
# A tibble: 87 x 4
name hair_color skin_color eye_color
<chr> <chr> <chr> <chr>
1 Luke Skywalker blond fair blue
2 C-3PO NA gold yellow
3 R2-D2 NA white, blue red
4 Darth Vader none white yellow
5 Leia Organa brown light brown
6 Owen Lars brown, grey light blue
7 Beru Whitesun lars brown light blue
8 R5-D4 NA white, red red
9 Biggs Darklighter black light brown
10 Obi-Wan Kenobi auburn, white fair blue-gray
# ... with 77 more rows
> starwars %>% group_by(species) %>%
+ summarise(n = n(),mass = mean(mass, na.rm = TRUE)) %>%
+ filter(n > 1)
# A tibble: 9 x 3
species n mass
<chr> <int> <dbl>
1 Droid 5 69.8
2 Gungan 3 74
3 Human 35 82.8
4 Kaminoan 2 88
5 Mirialan 2 53.1
6 Twi'lek 2 55
7 Wookiee 2 124
8 Zabrak 2 80
9 NA 5 48