Tổng hợp / tóm tắt nhiều biến cho mỗi nhóm (ví dụ: tổng, trung bình)


153

Từ một khung dữ liệu, là có một cách dễ dàng để tổng hợp ( sum, mean, maxet c) nhiều biến cùng một lúc?

Dưới đây là một số dữ liệu mẫu:

library(lubridate)
days = 365*2
date = seq(as.Date("2000-01-01"), length = days, by = "day")
year = year(date)
month = month(date)
x1 = cumsum(rnorm(days, 0.05)) 
x2 = cumsum(rnorm(days, 0.05))
df1 = data.frame(date, year, month, x1, x2)

Tôi muốn đồng thời tổng hợp các biến x1x2biến từ df2khung dữ liệu theo năm và tháng. Đoạn mã sau tổng hợp x1biến, nhưng cũng có thể tổng hợp đồng thời x2biến không?

### aggregate variables by year month
df2=aggregate(x1 ~ year+month, data=df1, sum, na.rm=TRUE)
head(df2)

Bất kỳ đề xuất sẽ được đánh giá rất cao.

Câu trả lời:


45

year()Chức năng này đến từ đâu?

Bạn cũng có thể sử dụng reshape2gói cho nhiệm vụ này:

require(reshape2)
df_melt <- melt(df1, id = c("date", "year", "month"))
dcast(df_melt, year + month ~ variable, sum)
#  year month         x1           x2
1  2000     1  -80.83405 -224.9540159
2  2000     2 -223.76331 -288.2418017
3  2000     3 -188.83930 -481.5601913
4  2000     4 -197.47797 -473.7137420
5  2000     5 -259.07928 -372.4563522

8
Các recastchức năng (cũng từ reshape2) tích hợp meltdcastchức năng trong một đi cho các nhiệm vụ như thế này:recast(df1, year + month ~ variable, sum, id.var = c("date", "year", "month"))
Jaap

184

Có, trong của bạn formula, bạn có thể cbindtổng hợp các biến số:

aggregate(cbind(x1, x2) ~ year + month, data = df1, sum, na.rm = TRUE)
   year month         x1          x2
1  2000     1   7.862002   -7.469298
2  2001     1 276.758209  474.384252
3  2000     2  13.122369 -128.122613
...
23 2000    12  63.436507  449.794454
24 2001    12 999.472226  922.726589

Xem ?aggregate, các formulađối số và các ví dụ.


3
Có thể cho cbind sử dụng các biến động?
pdb

14
Điều đáng chú ý là khi bất kỳ biến nào trong cbind có NA, hàng sẽ bị loại bỏ cho mọi biến trong cbind. Đây không phải là hành vi tôi đã mong đợi.
pdb

1
Điều gì xảy ra nếu tôi thay vì x1 và x2 Tôi muốn sử dụng tất cả các biến còn lại (trừ năm, tháng)
Clock Slave

7
@ClockSlave, sau đó bạn chỉ cần sử dụng .trên LHS. aggregate(. ~ year + month, df1, sum, na.rm = TRUE). Trong ví dụ này, sum"ngày" không có ý nghĩa gì cả ....
A5C1D2H2I1M1N2O1R2T1

5
Điều gì xảy ra nếu tôi không muốn hai biến nhưng hai hàm?. Ví dụ: trung bình và sd.
skan

51

Sử dụng data.tablegói nhanh (hữu ích cho các bộ dữ liệu lớn hơn)

https://github.com/Rdatitable/data.table/wiki

library(data.table)
df2 <- setDT(df1)[, lapply(.SD, sum), by=.(year, month), .SDcols=c("x1","x2")]
setDF(df2) # convert back to dataframe

Sử dụng gói plyr

require(plyr)
df2 <- ddply(df1, c("year", "month"), function(x) colSums(x[c("x1", "x2")]))

Sử dụng tóm tắt () từ gói Hmisc (tiêu đề cột rất lộn xộn trong ví dụ của tôi)

# need to detach plyr because plyr and Hmisc both have a summarize()
detach(package:plyr)
require(Hmisc)
df2 <- with(df1, summarize( cbind(x1, x2), by=llist(year, month), FUN=colSums))

Tại sao không làm điều này cho tùy chọn data.table : dt[, .(x1.sum = sum(x1), x2.sum = sum(x2), by = c(year, month)?
Bulat

48

Với dplyrgói, bạn có thể sử dụng summarise_all, summarise_athoặc summarise_ifchức năng để tổng hợp nhiều biến cùng một lúc. Đối với tập dữ liệu mẫu, bạn có thể làm điều này như sau:

library(dplyr)
# summarising all non-grouping variables
df2 <- df1 %>% group_by(year, month) %>% summarise_all(sum)

# summarising a specific set of non-grouping variables
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(x1, x2), sum)
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(-date), sum)

# summarising a specific set of non-grouping variables using select_helpers
# see ?select_helpers for more options
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(starts_with('x')), sum)
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(matches('.*[0-9]')), sum)

# summarising a specific set of non-grouping variables based on condition (class)
df2 <- df1 %>% group_by(year, month) %>% summarise_if(is.numeric, sum)

Kết quả của hai tùy chọn sau:

    year month        x1         x2
   <dbl> <dbl>     <dbl>      <dbl>
1   2000     1 -73.58134  -92.78595
2   2000     2 -57.81334 -152.36983
3   2000     3 122.68758  153.55243
4   2000     4 450.24980  285.56374
5   2000     5 678.37867  384.42888
6   2000     6 792.68696  530.28694
7   2000     7 908.58795  452.31222
8   2000     8 710.69928  719.35225
9   2000     9 725.06079  914.93687
10  2000    10 770.60304  863.39337
# ... with 14 more rows

Lưu ý: summarise_eachlà phản đối ủng hộ summarise_all, summarise_atsummarise_if.


Như đã đề cập trong nhận xét của tôi ở trên , bạn cũng có thể sử dụng recastchức năng từ reshape2-package:

library(reshape2)
recast(df1, year + month ~ variable, sum, id.var = c("date", "year", "month"))

Điều này sẽ cho bạn kết quả tương tự.


8

Điều thú vị là, cơ sở R aggregate's data.framephương pháp không được trưng bày ở đây, trên giao diện công thức được sử dụng, vì vậy cho đầy đủ:

aggregate(
  x = df1[c("x1", "x2")],
  by = df1[c("year", "month")],
  FUN = sum, na.rm = TRUE
)

Sử dụng chung hơn phương pháp data.frame của tổng hợp:

Vì chúng tôi đang cung cấp một

  • data.framenhư x
  • a list( data.framecũng là a list) vì by, điều này rất hữu ích nếu chúng ta cần sử dụng nó một cách năng động, ví dụ như sử dụng các cột khác để tổng hợp và tổng hợp bởi rất đơn giản
  • cũng với các chức năng tổng hợp tùy chỉnh

Ví dụ như vậy:

colsToAggregate <- c("x1")
aggregateBy <- c("year", "month")
dummyaggfun <- function(v, na.rm = TRUE) {
  c(sum = sum(v, na.rm = na.rm), mean = mean(v, na.rm = na.rm))
}

aggregate(df1[colsToAggregate], by = df1[aggregateBy], FUN = dummyaggfun)

1

Với develphiên bản dplyr(phiên bản - ‘0.8.99.9000’), chúng ta cũng có thể sử dụng summariseđể áp dụng chức năng trên nhiều cột vớiacross

library(dplyr)
df1 %>% 
    group_by(year, month) %>%
    summarise(across(starts_with('x'), sum))
# A tibble: 24 x 4
# Groups:   year [2]
#    year month     x1     x2
#   <dbl> <dbl>  <dbl>  <dbl>
# 1  2000     1   11.7  52.9 
# 2  2000     2  -74.1 126.  
# 3  2000     3 -132.  149.  
# 4  2000     4 -130.    4.12
# 5  2000     5  -91.6 -55.9 
# 6  2000     6  179.   73.7 
# 7  2000     7   95.0 409.  
# 8  2000     8  255.  283.  
# 9  2000     9  489.  331.  
#10  2000    10  719.  305.  
# … with 14 more rows

1

Để có cách tiếp cận linh hoạt hơn và nhanh hơn để tổng hợp dữ liệu, hãy kiểm tra collapchức năng trong gói thu gọn R có sẵn trên CRAN:

library(collapse)
# Simple aggregation with one function
head(collap(df1, x1 + x2 ~ year + month, fmean))

  year month        x1        x2
1 2000     1 -1.217984  4.008534
2 2000     2 -1.117777 11.460301
3 2000     3  5.552706  8.621904
4 2000     4  4.238889 22.382953
5 2000     5  3.124566 39.982799
6 2000     6 -1.415203 48.252283

# Customized: Aggregate columns with different functions
head(collap(df1, x1 + x2 ~ year + month, 
      custom = list(fmean = c("x1", "x2"), fmedian = "x2")))

  year month  fmean.x1  fmean.x2 fmedian.x2
1 2000     1 -1.217984  4.008534   3.266968
2 2000     2 -1.117777 11.460301  11.563387
3 2000     3  5.552706  8.621904   8.506329
4 2000     4  4.238889 22.382953  20.796205
5 2000     5  3.124566 39.982799  39.919145
6 2000     6 -1.415203 48.252283  48.653926

# You can also apply multiple functions to all columns
head(collap(df1, x1 + x2 ~ year + month, list(fmean, fmin, fmax)))

  year month  fmean.x1    fmin.x1  fmax.x1  fmean.x2   fmin.x2  fmax.x2
1 2000     1 -1.217984 -4.2460775 1.245649  4.008534 -1.720181 10.47825
2 2000     2 -1.117777 -5.0081858 3.330872 11.460301  9.111287 13.86184
3 2000     3  5.552706  0.1193369 9.464760  8.621904  6.807443 11.54485
4 2000     4  4.238889  0.8723805 8.627637 22.382953 11.515753 31.66365
5 2000     5  3.124566 -1.5985090 7.341478 39.982799 31.957653 46.13732
6 2000     6 -1.415203 -4.6072295 2.655084 48.252283 42.809211 52.31309

# When you do that, you can also return the data in a long format
head(collap(df1, x1 + x2 ~ year + month, list(fmean, fmin, fmax), return = "long"))

  Function year month        x1        x2
1    fmean 2000     1 -1.217984  4.008534
2    fmean 2000     2 -1.117777 11.460301
3    fmean 2000     3  5.552706  8.621904
4    fmean 2000     4  4.238889 22.382953
5    fmean 2000     5  3.124566 39.982799
6    fmean 2000     6 -1.415203 48.252283

Lưu ý : Bạn có thể sử dụng các hàm cơ bản như mean, maxv.v. collap, nhưng fmean, fmaxv.v ... là các hàm được nhóm dựa trên C ++ được cung cấp trong gói thu gọn nhanh hơn đáng kể (nghĩa là hiệu suất trên các tập hợp dữ liệu lớn giống như data.table trong khi cung cấp tính linh hoạt cao hơn và các chức năng được nhóm nhanh này cũng có thể được sử dụng mà không có collap).

Note2 : collapcũng hỗ trợ tổng hợp dữ liệu đa biến linh hoạt, tất nhiên bạn có thể thực hiện bằng cách sử dụng customđối số, nhưng bạn cũng có thể áp dụng các hàm cho các cột số và không số theo cách bán tự động:

# wlddev is a data set of World Bank Indicators provided in the collapse package
head(wlddev)

      country iso3c       date year decade     region     income  OECD PCGDP LIFEEX GINI       ODA
1 Afghanistan   AFG 1961-01-01 1960   1960 South Asia Low income FALSE    NA 32.292   NA 114440000
2 Afghanistan   AFG 1962-01-01 1961   1960 South Asia Low income FALSE    NA 32.742   NA 233350000
3 Afghanistan   AFG 1963-01-01 1962   1960 South Asia Low income FALSE    NA 33.185   NA 114880000
4 Afghanistan   AFG 1964-01-01 1963   1960 South Asia Low income FALSE    NA 33.624   NA 236450000
5 Afghanistan   AFG 1965-01-01 1964   1960 South Asia Low income FALSE    NA 34.060   NA 302480000
6 Afghanistan   AFG 1966-01-01 1965   1960 South Asia Low income FALSE    NA 34.495   NA 370250000

# This aggregates the data, applying the mean to numeric and the statistical mode to categorical columns
head(collap(wlddev, ~ iso3c + decade, FUN = fmean, catFUN = fmode))

  country iso3c       date   year decade                     region      income  OECD    PCGDP   LIFEEX GINI      ODA
1   Aruba   ABW 1961-01-01 1962.5   1960 Latin America & Caribbean  High income FALSE       NA 66.58583   NA       NA
2   Aruba   ABW 1967-01-01 1970.0   1970 Latin America & Caribbean  High income FALSE       NA 69.14178   NA       NA
3   Aruba   ABW 1976-01-01 1980.0   1980 Latin America & Caribbean  High income FALSE       NA 72.17600   NA 33630000
4   Aruba   ABW 1987-01-01 1990.0   1990 Latin America & Caribbean  High income FALSE 23677.09 73.45356   NA 41563333
5   Aruba   ABW 1996-01-01 2000.0   2000 Latin America & Caribbean  High income FALSE 26766.93 73.85773   NA 19857000
6   Aruba   ABW 2007-01-01 2010.0   2010 Latin America & Caribbean  High income FALSE 25238.80 75.01078   NA       NA

# Note that by default (argument keep.col.order = TRUE) the column order is also preserved

0

Đến bữa tiệc muộn, nhưng gần đây đã tìm ra một cách khác để có được số liệu thống kê tóm tắt.

library(psych) describe(data)

Sẽ xuất ra: trung bình, tối thiểu, tối đa, độ lệch chuẩn, n, lỗi tiêu chuẩn, kurtosis, độ lệch, trung vị và phạm vi cho mỗi biến.


Câu hỏi là về việc tập hợp theo nhóm , nhưng describekhông làm gì theo nhóm ...
Gregor Thomas

describe.by(column, group = grouped_column)sẽ nhóm các giá trị
britt

4
Vâng, đặt nó trong câu trả lời sau đó! Đừng giấu nó trong một bình luận!
Gregor Thomas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.