使用聚合来方便计算
Use aggregate to facilitate calculations
所以最近我一直在学习聚合的功能,我发现它对我处理的大型数据集非常有用。通常我手动操作 excel 中的数据,虽然有效,但非常耗时。
所以我想知道是否可以完成以下操作。我有一个结构类似的数据集(但更大):
Fruit Crate Mass
Apple A 4
Banana A 3.4
Orange B 2
Apple C 2.1
Apple C 4.5
Banana C 5
Orange D 1
Apple D 1.3
Orange D 2.4
Orange D 3.2
Orange E 2
Banana E 1.1
Banana E 0.7
Apple E 2
现在我知道我得到了每个板条箱的质量:
TotalCrate<-aggregate(data$Mass,list(crate=data$Crate), sum)
然后我得到每个板条箱每个水果的质量:
FruitperCrate<-aggregate(data$Mass, list(fruit=data$Fruit, crate=data$Crate), sum)
现在有没有一种方法可以获得每个板条箱的水果质量百分比,所以基本上,有没有一种方法可以将水果质量除以每个板条箱的总质量?如果是这样,我该如何做以供将来参考。
感谢任何帮助。
谢谢
这里有一个解决方案,使用 data.table
,当然还有其他方法:
library( data.table )
setDT( data )
data[ , mass := sum( mass ), by = .( crate, fruit ) ]
data <- unique( data )
data[ , total.mass.crate := sum( mass ), by = crate ]
data[ , percentage.mass.crate := ( mass / total.mass.crate ) * 100 ]
所以我们首先汇总每个板条箱中每个水果的质量(因为我注意到有些水果在一个板条箱中不止一次列出)以获得板条箱中该水果的总质量。然后我们添加一列来显示每个板条箱的总质量,显示每一行的值。然后,通过将每个水果的质量除以该箱子的总质量,我们得到箱子中每个水果的质量百分比。
1)先用Fruit
和Crate
聚合,然后用ave
和prop.table
得到比例箱子里的每个水果:
ag <- aggregate(Mass ~ Fruit + Crate, data, sum)
tr <- transform(ag, percent = 100 * ave(Mass, Crate, FUN = prop.table))
给予:
> tr
Fruit Crate Mass percent
1 Apple A 4.0 54.05405
2 Banana A 3.4 45.94595
3 Orange B 2.0 100.00000
4 Apple C 6.6 56.89655
5 Banana C 5.0 43.10345
6 Apple D 1.3 16.45570
7 Orange D 6.6 83.54430
8 Apple E 2.0 34.48276
9 Banana E 1.8 31.03448
10 Orange E 2.0 34.48276
或图形化:
library(ggplot2)
ggplot(tr, aes(Crate, percent, fill = Fruit)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = c("red", "yellow", "orange"))
1a) 这也可以用这样的 magrittr 管道表示:
library(magrittr)
data %>%
do(aggregate(Mass ~ Fruit + Crate, ., sum)) %>%
transform(percent = 100 * ave(Mass, Crate, FUN = prop.table))
2) 这是使用遵循类似逻辑的 dplyr 的替代方法:
library(dplyr)
data %>%
group_by(Crate, Fruit) %>%
summarize(Mass = sum(Mass)) %>%
ungroup() %>%
group_by(Crate) %>%
mutate(percent = 100 * prop.table(Mass)) %>%
ungroup()
给予:
# A tibble: 10 x 4
Crate Fruit Mass percent
<fctr> <fctr> <dbl> <dbl>
1 A Apple 4.0 54.05405
2 A Banana 3.4 45.94595
3 B Orange 2.0 100.00000
4 C Apple 6.6 56.89655
5 C Banana 5.0 43.10345
6 D Apple 1.3 16.45570
7 D Orange 6.6 83.54430
8 E Apple 2.0 34.48276
9 E Banana 1.8 31.03448
10 E Orange 2.0 34.48276
3) 二维布局可以使用 xtabs
:
xt <- 100 * prop.table(xtabs(Mass ~ Crate + Fruit, data), 1)
给予:
> xt
Fruit
Crate Apple Banana Orange
A 54.05405 45.94595 0.00000
B 0.00000 0.00000 100.00000
C 56.89655 43.10345 0.00000
D 16.45570 0.00000 83.54430
E 34.48276 31.03448 34.48276
可以很容易地用如下图表显示:
plot(xt, col = c("red", "yellow", "orange"),
main = "Proportion of Mass of Fruit per Crates")
给予:
二维布局可以改成长格式 ftable
:
ftable(xt, row.vars = 1:2)
给予:
Crate Fruit
A Apple 54.05405
Banana 45.94595
Orange 0.00000
B Apple 0.00000
Banana 0.00000
Orange 100.00000
C Apple 56.89655
Banana 43.10345
Orange 0.00000
D Apple 16.45570
Banana 0.00000
Orange 83.54430
E Apple 34.48276
Banana 31.03448
Orange 34.48276
注1:题目中的两行代码可以用公式写成这样:
aggregate(Mass ~ Crate, data, sum)
aggregate(Mass ~ Fruit + Crate, data, sum)
注释 2: 以可重现形式使用的输入是:
Lines <- "Fruit Crate Mass
Apple A 4
Banana A 3.4
Orange B 2
Apple C 2.1
Apple C 4.5
Banana C 5
Orange D 1
Apple D 1.3
Orange D 2.4
Orange D 3.2
Orange E 2
Banana E 1.1
Banana E 0.7
Apple E 2"
data <- read.table(text = Lines, header = TRUE)
所以最近我一直在学习聚合的功能,我发现它对我处理的大型数据集非常有用。通常我手动操作 excel 中的数据,虽然有效,但非常耗时。
所以我想知道是否可以完成以下操作。我有一个结构类似的数据集(但更大):
Fruit Crate Mass
Apple A 4
Banana A 3.4
Orange B 2
Apple C 2.1
Apple C 4.5
Banana C 5
Orange D 1
Apple D 1.3
Orange D 2.4
Orange D 3.2
Orange E 2
Banana E 1.1
Banana E 0.7
Apple E 2
现在我知道我得到了每个板条箱的质量:
TotalCrate<-aggregate(data$Mass,list(crate=data$Crate), sum)
然后我得到每个板条箱每个水果的质量:
FruitperCrate<-aggregate(data$Mass, list(fruit=data$Fruit, crate=data$Crate), sum)
现在有没有一种方法可以获得每个板条箱的水果质量百分比,所以基本上,有没有一种方法可以将水果质量除以每个板条箱的总质量?如果是这样,我该如何做以供将来参考。
感谢任何帮助。
谢谢
这里有一个解决方案,使用 data.table
,当然还有其他方法:
library( data.table )
setDT( data )
data[ , mass := sum( mass ), by = .( crate, fruit ) ]
data <- unique( data )
data[ , total.mass.crate := sum( mass ), by = crate ]
data[ , percentage.mass.crate := ( mass / total.mass.crate ) * 100 ]
所以我们首先汇总每个板条箱中每个水果的质量(因为我注意到有些水果在一个板条箱中不止一次列出)以获得板条箱中该水果的总质量。然后我们添加一列来显示每个板条箱的总质量,显示每一行的值。然后,通过将每个水果的质量除以该箱子的总质量,我们得到箱子中每个水果的质量百分比。
1)先用Fruit
和Crate
聚合,然后用ave
和prop.table
得到比例箱子里的每个水果:
ag <- aggregate(Mass ~ Fruit + Crate, data, sum)
tr <- transform(ag, percent = 100 * ave(Mass, Crate, FUN = prop.table))
给予:
> tr
Fruit Crate Mass percent
1 Apple A 4.0 54.05405
2 Banana A 3.4 45.94595
3 Orange B 2.0 100.00000
4 Apple C 6.6 56.89655
5 Banana C 5.0 43.10345
6 Apple D 1.3 16.45570
7 Orange D 6.6 83.54430
8 Apple E 2.0 34.48276
9 Banana E 1.8 31.03448
10 Orange E 2.0 34.48276
或图形化:
library(ggplot2)
ggplot(tr, aes(Crate, percent, fill = Fruit)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = c("red", "yellow", "orange"))
1a) 这也可以用这样的 magrittr 管道表示:
library(magrittr)
data %>%
do(aggregate(Mass ~ Fruit + Crate, ., sum)) %>%
transform(percent = 100 * ave(Mass, Crate, FUN = prop.table))
2) 这是使用遵循类似逻辑的 dplyr 的替代方法:
library(dplyr)
data %>%
group_by(Crate, Fruit) %>%
summarize(Mass = sum(Mass)) %>%
ungroup() %>%
group_by(Crate) %>%
mutate(percent = 100 * prop.table(Mass)) %>%
ungroup()
给予:
# A tibble: 10 x 4
Crate Fruit Mass percent
<fctr> <fctr> <dbl> <dbl>
1 A Apple 4.0 54.05405
2 A Banana 3.4 45.94595
3 B Orange 2.0 100.00000
4 C Apple 6.6 56.89655
5 C Banana 5.0 43.10345
6 D Apple 1.3 16.45570
7 D Orange 6.6 83.54430
8 E Apple 2.0 34.48276
9 E Banana 1.8 31.03448
10 E Orange 2.0 34.48276
3) 二维布局可以使用 xtabs
:
xt <- 100 * prop.table(xtabs(Mass ~ Crate + Fruit, data), 1)
给予:
> xt
Fruit
Crate Apple Banana Orange
A 54.05405 45.94595 0.00000
B 0.00000 0.00000 100.00000
C 56.89655 43.10345 0.00000
D 16.45570 0.00000 83.54430
E 34.48276 31.03448 34.48276
可以很容易地用如下图表显示:
plot(xt, col = c("red", "yellow", "orange"),
main = "Proportion of Mass of Fruit per Crates")
给予:
二维布局可以改成长格式 ftable
:
ftable(xt, row.vars = 1:2)
给予:
Crate Fruit
A Apple 54.05405
Banana 45.94595
Orange 0.00000
B Apple 0.00000
Banana 0.00000
Orange 100.00000
C Apple 56.89655
Banana 43.10345
Orange 0.00000
D Apple 16.45570
Banana 0.00000
Orange 83.54430
E Apple 34.48276
Banana 31.03448
Orange 34.48276
注1:题目中的两行代码可以用公式写成这样:
aggregate(Mass ~ Crate, data, sum)
aggregate(Mass ~ Fruit + Crate, data, sum)
注释 2: 以可重现形式使用的输入是:
Lines <- "Fruit Crate Mass
Apple A 4
Banana A 3.4
Orange B 2
Apple C 2.1
Apple C 4.5
Banana C 5
Orange D 1
Apple D 1.3
Orange D 2.4
Orange D 3.2
Orange E 2
Banana E 1.1
Banana E 0.7
Apple E 2"
data <- read.table(text = Lines, header = TRUE)