我有一个包含 ID、类型和区域的数据框,我想一次执行两个操作
ID Type Area
1 Aa 0.02
2 Ag 0.12
2 Ag 0.14
2 Ag 0.80
2 Bm 0.20
2 Xm 0.13
预期的结果是
ID Type count area
1 Aa 1 0.02
2 Ag 3 1.06 (sum)
2 Bm 1 0.20
2 Xm 1 0.13
我有多达 100-150 个 ID,类型、计数和断面积因具有相同 ID 的每种类型而异,同时执行求和和计数并将类型和 ID 保留在数据框中的最佳方法是什么?
谢谢
1) Base R -- aggregate Counts 只是一个常数列的总和,所以使用
DF
在末尾的注释中重复显示,我们添加这样一个列并使用 sum
进行聚合。没有使用包。
aggregate(cbind(Count, Area) ~ ID + Type, transform(DF, Count = 1), sum)
给予:
ID Type Count Area
1 1 Aa 1 0.02
2 2 Ag 3 1.06
3 2 Bm 1 0.20
4 2 Xm 1 0.13
2) Base R -- by 仅使用 base R 而不依赖于添加一列的技巧的方法是使用
by
。 by
调用生成类 by
的列表,而 do.call("rbind", ...)
将其转换为数据框。
do.call("rbind", by(DF, DF[1:2], with,
data.frame(ID = ID[1], Type = Type[1], Count = length(ID), Area = sum(Area))))
给予:
ID Type Count Area
1 1 Aa 1 0.02
2 2 Ag 3 1.06
3 2 Bm 1 0.20
4 2 Xm 1 0.13
3) sqldf SQL 允许单独和同时应用计数和求和。
library(sqldf)
sqldf("select ID, Type, count(*) as Count, sum(Area) as Area
from DF
group by 1, 2")
给予:
ID Type Count Area
1 1 Aa 1 0.02
2 2 Ag 3 1.06
3 2 Bm 1 0.20
4 2 Xm 1 0.13
4) data.table 也可以使用data.table包
library(data.table)
DT <- as.data.table(DF)
DT[, .(Count = .N, Area = sum(Area)), by = "ID,Type"]
给予:
ID Type Count Area
1: 1 Aa 1 0.02
2: 2 Ag 3 1.06
3: 2 Bm 1 0.20
4: 2 Xm 1 0.13
Lines <- "ID Type Area
1 Aa 0.02
2 Ag 0.12
2 Ag 0.14
2 Ag 0.80
2 Bm 0.20
2 Xm 0.13 "
DF <- read.table(text = Lines, header = TRUE)
我们可以使用
dplyr
。使用包
library(dplyr)
df1 %>%
group_by(ID, Type) %>%
summarise(count = n(), Area = sum(Area))
# A tibble: 4 x 4
# Groups: ID [2]
# ID Type count Area
# <int> <chr> <int> <dbl>
#1 1 Aa 1 0.02
#2 2 Ag 3 1.06
#3 2 Bm 1 0.2
#4 2 Xm 1 0.13
或来自
by
的base R
- 请注意base R
也包括一些包...
by(df1['Area'], df1[1:2], FUN = function(x) cbind(count = nrow(x), Area = sum(x)))
df1 <- structure(list(ID = c(1L, 2L, 2L, 2L, 2L, 2L), Type = c("Aa",
"Ag", "Ag", "Ag", "Bm", "Xm"), Area = c(0.02, 0.12, 0.14, 0.8,
0.2, 0.13)), class = "data.frame", row.names = c(NA, -6L))
plyr
中的另一种可能性:
library(plyr)
ddply(DF, .(ID,Type), summarize, Count=length(Area), Area=sum(Area))
# ID Type Count Area
# 1 1 Aa 1 0.02
# 2 2 Ag 3 1.06
# 3 2 Bm 1 0.20
# 4 2 Xm 1 0.13
如果你的数据很大,我推荐
data.table
:
library(data.table)
setDT(df)[, .(Area=sum(Area), Count=.N), .(ID, Type)]