รวม / สรุปตัวแปรหลายตัวต่อกลุ่ม (เช่นผลรวม, ค่าเฉลี่ย)


154

จากกรอบข้อมูลจะมีวิธีที่ง่ายต่อการรวม ( sum, mean, maxet c) ตัวแปรหลายคนพร้อมกัน?

ด้านล่างเป็นข้อมูลตัวอย่างบางส่วน:

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)

ฉันต้องการรวมx1และx2ตัวแปรจากdf2data frame ตามปีและเดือนพร้อมกัน โค้ดต่อไปนี้จะรวมx1ตัวแปร แต่ก็เป็นไปได้ที่จะรวมx2ตัวแปรพร้อมกันหรือไม่

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

ข้อเสนอแนะใด ๆ ที่จะได้รับการชื่นชมอย่างมาก.

คำตอบ:


45

year()ฟังก์ชั่นนี้มาจากไหน?

คุณสามารถใช้reshape2แพ็คเกจสำหรับงานนี้:

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
recastฟังก์ชั่น (จากreshape2) รวมmeltและdcastฟังก์ชั่นในหนึ่งไปสำหรับงานเช่นนี้recast(df1, year + month ~ variable, sum, id.var = c("date", "year", "month"))
Jaap

184

ใช่ในของformulaคุณคุณสามารถcbindรวมตัวแปรตัวเลข:

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

ดู?aggregateที่formulaการโต้แย้งและตัวอย่าง


3
เป็นไปได้หรือไม่ที่ cbind จะใช้ตัวแปรแบบไดนามิก?
pdb

14
เป็นที่น่าสังเกตว่าเมื่อตัวแปรใด ๆ ที่อยู่ใน cbind มี NA แถวจะถูกลบสำหรับทุกตัวแปรใน cbind นี่ไม่ใช่พฤติกรรมที่ฉันคาดหวัง
pdb

1
จะทำอย่างไรถ้าฉันแทน x1 และ x2 ฉันต้องการใช้ตัวแปรที่เหลือทั้งหมด (นอกเหนือจากปี, เดือน)
Clock Slave

7
@ClockSlave แล้วคุณต้องใช้.กับ LHS aggregate(. ~ year + month, df1, sum, na.rm = TRUE). ในตัวอย่างนี้sumสำหรับ "date" ไม่สมเหตุสมผลแม้ว่า ....
A5C1D2H2I1M1N2O1R2T1

5
ถ้าฉันไม่ต้องการตัวแปรสองตัว แต่เป็นสองฟังก์ชั่น ตัวอย่างเช่น mean และ sd
skan

51

การใช้data.tableแพคเกจซึ่งรวดเร็ว (มีประโยชน์สำหรับชุดข้อมูลขนาดใหญ่)

https://github.com/Rdatatable/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

การใช้แพ็คเกจ plyr

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

ใช้สรุป () จากแพคเกจ Hmisc (ส่วนหัวคอลัมน์จะยุ่งในตัวอย่างของฉันแม้ว่า)

# 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))

ทำไมไม่ทำเช่นนี้สำหรับตัวเลือก data.table: dt[, .(x1.sum = sum(x1), x2.sum = sum(x2), by = c(year, month)?
Bulat

48

ด้วยdplyrแพคเกจที่คุณสามารถใช้summarise_all, summarise_atหรือsummarise_ifฟังก์ชั่นการรวมตัวแปรหลายคนพร้อมกัน สำหรับชุดข้อมูลตัวอย่างคุณสามารถทำได้ดังนี้:

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)

ผลลัพธ์ของสองตัวเลือกหลัง:

    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

หมายเหตุ: summarise_eachจะเลิกในความโปรดปรานของsummarise_all, และsummarise_atsummarise_if


ตามที่ระบุไว้ในความคิดเห็นของฉันข้างต้นคุณยังสามารถใช้recastฟังก์ชั่นจากreshape2- แพคเกจ:

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

ซึ่งจะให้ผลลัพธ์เดียวกัน


8

ที่น่าสนใจฐาน R aggregate's data.frameวิธีการไม่ได้รับการจัดแสดงที่นี่ด้านบนอินเตอร์เฟซสูตรถูกนำมาใช้เพื่อให้ครบถ้วน:

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

การใช้งานทั่วไปเพิ่มเติมของวิธี data.frame รวม:

เนื่องจากเราให้บริการ

  • data.frameเป็นxและ
  • a list( data.frameเป็น a list) เนื่องจากbyมันมีประโยชน์มากถ้าเราจำเป็นต้องใช้มันในลักษณะไดนามิกเช่นการใช้คอลัมน์อื่น ๆ เพื่อรวมและรวมโดยง่ายมาก
  • ยังมีฟังก์ชั่นการรวมตัวที่กำหนดเองทำ

ตัวอย่างเช่น:

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

ด้วยdevelรุ่นdplyr(รุ่น - ‘0.8.99.9000’) เรายังสามารถใช้summariseเพื่อใช้ฟังก์ชั่นในหลายคอลัมน์ด้วยacross

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

สำหรับวิธีการรวบรวมข้อมูลที่ยืดหยุ่นและรวดเร็วยิ่งขึ้นลองดูcollapฟังก์ชั่นในแพ็คเกจ R ยุบที่มีอยู่ใน 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

หมายเหตุ : คุณสามารถใช้ฟังก์ชั่นพื้นฐานเช่นmean, maxอื่น ๆ ด้วยcollapแต่fmean, fmaxเป็นฟังก์ชั่นที่จัดกลุ่มตาม C ++ ในแพ็คเกจยุบซึ่งเร็วกว่าอย่างมาก (เช่นประสิทธิภาพของการรวมข้อมูลขนาดใหญ่จะเหมือนกับdata.tableขณะที่ให้ความยืดหยุ่นมากขึ้นและ ฟังก์ชันที่จัดกลุ่มอย่างรวดเร็วเหล่านี้สามารถใช้งานได้โดยไม่ต้องcollap)

Note2 : collapยังรองรับการรวมข้อมูลหลายประเภทที่มีความยืดหยุ่นซึ่งแน่นอนว่าคุณสามารถใช้customอาร์กิวเมนต์ได้ แต่คุณสามารถใช้ฟังก์ชันกับคอลัมน์ที่เป็นตัวเลขและไม่ใช่ตัวเลขได้ด้วยวิธีกึ่งอัตโนมัติ:

# 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

ไปงานปาร์ตี้สาย แต่เมื่อเร็ว ๆ นี้พบวิธีการอื่นเพื่อรับสถิติสรุป

library(psych) describe(data)

จะส่งออก: หมายถึง, นาที, สูงสุด, ส่วนเบี่ยงเบนมาตรฐาน, n, ข้อผิดพลาดมาตรฐาน, kurtosis, เบ้, มัธยฐานและช่วงสำหรับแต่ละตัวแปร


คำถามเกี่ยวกับการรวมกลุ่มตามกลุ่มแต่describeไม่ได้ทำสิ่งใดเป็นกลุ่ม ...
Gregor Thomas

describe.by(column, group = grouped_column)น้ำพระทัยกลุ่มค่า
Britt

4
เอาคำตอบนั้นออกไป! อย่าซ่อนไว้ในความคิดเห็น!
Gregor Thomas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.