如何在R中对数据帧执行求和和计数

uda*_*day 2 aggregate r

我有一个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    
Run Code Online (Sandbox Code Playgroud)

预期的结果是

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 
Run Code Online (Sandbox Code Playgroud)

我有多达100-150个ID,并且每种类型,具有相同ID的计数和基本面积都不同,什么是最好的方法来同时执行总和和计数并在数据帧中保留类型和ID?

谢谢

G. *_*eck 6

1)基数R-聚合计数只是一个常数列的总和,因此,使用“可DF重复地显示在注释中”结尾处的注释,我们添加这样的列并使用进行聚合sum。不使用任何软件包。

aggregate(cbind(Count, Area) ~ ID + Type, transform(DF, Count = 1), sum)
Run Code Online (Sandbox Code Playgroud)

给予:

  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
Run Code Online (Sandbox Code Playgroud)

2)基本R-通过使用仅使用基本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))))
Run Code Online (Sandbox Code Playgroud)

给予:

  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
Run Code Online (Sandbox Code Playgroud)

3)sqldf SQL允许单独和同时应用计数和总和。

library(sqldf)
sqldf("select ID, Type, count(*) as Count, sum(Area) as Area
  from DF
  group by 1, 2")
Run Code Online (Sandbox Code Playgroud)

给予:

  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
Run Code Online (Sandbox Code Playgroud)

4)data.table也可以使用data.table包。

library(data.table)

DT <- as.data.table(DF)
DT[, .(Count = .N, Area = sum(Area)), by = "ID,Type"]
Run Code Online (Sandbox Code Playgroud)

给予:

   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
Run Code Online (Sandbox Code Playgroud)

注意

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)
Run Code Online (Sandbox Code Playgroud)

  • 该问题并未指定ID是否为数字,而是在答案的注释中确实将其显示为数字。如果您有什么不同,请先将其转换为数字。这说明了为什么在答案中像在答案中一样提供一个可重现的示例很重要。 (3认同)

akr*_*run 5

我们可以使用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
Run Code Online (Sandbox Code Playgroud)

或使用byfrom base R- 请注意,base R还包括一些软件包...

by(df1['Area'], df1[1:2], FUN = function(x) cbind(count = nrow(x), Area = sum(x)))
Run Code Online (Sandbox Code Playgroud)

数据

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))
Run Code Online (Sandbox Code Playgroud)