Grup başına birden çok değişkeni topla / özetle (örneğin, toplam, ortalama)


154

Bir veri çerçevesi kaynaktan (bir araya getirmek için kolay bir yol olup sum, mean, maxeş zamanlı olarak ve c) birden çok değişken?

Aşağıda bazı örnek veriler verilmiştir:

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)

Veri çerçevesindeki x1ve x2değişkenlerini aynı anda df2yıl ve aya göre toplamak istiyorum . Aşağıdaki kod x1değişkeni toplar, ancak değişkeni aynı anda toplamak da mümkün müdür x2?

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

Herhangi bir öneri büyük mutluluk duyacağız.

Yanıtlar:


45

Bu year()işlev nereden geliyor?

reshape2Paketi bu görev için de kullanabilirsiniz :

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
recastFonksiyonu (aynı zamanda den reshape2) bütünleştirir meltve dcastbunun gibi görevler için tek seferde işlevi:recast(df1, year + month ~ variable, sum, id.var = c("date", "year", "month"))
Jaap

184

Evet, formulasizde, cbindtoplanacak sayısal değişkenleri yapabilirsiniz :

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

Bakınız ?aggregate, formulaargüman ve örnekler.


3
Cbind için dinamik değişkenler kullanılabilir mi?
pdb

14
Cbind içindeki değişkenlerden herhangi birinin bir NA değeri olduğunda satırın cbind içindeki her değişken için bırakılacağını belirtmek gerekir. Bu beklediğim davranış değil.
pdb

1
x1 ve x2 yerine kalan tüm değişkenleri kullanmak istersem (yıl, ay hariç)
Clock Slave

7
@ClockSlave, o zaman sadece LHS'de kullanmanız gerekir .. aggregate(. ~ year + month, df1, sum, na.rm = TRUE). Bu örnekte, sum"tarih" için bir anlam ifade etmiyor ....
A5C1D2H2I1M1N2O1R2T1

5
İki değişken değil iki işlev istemem ne olur? Örneğin ortalama ve sd.
skan

51

data.tableHızlı olan paketi kullanma (daha büyük veri kümeleri için yararlıdır)

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 paketini kullanma

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

Hmisc paketinden summarize () kullanmak (örneğimde sütun başlıkları dağınık)

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

neden data.table seçeneği için bunu yapmıyorsunuz dt[, .(x1.sum = sum(x1), x2.sum = sum(x2), by = c(year, month)?
Bulat

48

İle dplyrpaket kullanabilirsiniz summarise_all, summarise_atya da summarise_ifaynı anda birden fazla değişkenleri ile fonksiyonları. Örnek veri kümesi için bunu aşağıdaki gibi yapabilirsiniz:

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)

Son iki seçeneğin sonucu:

    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

Not: summarise_eachlehine kullanımdan kaldırılmıştır summarise_all, summarise_atve summarise_if.


Yukarıdaki yorumumda belirtildiği gibi , -package recastişlevini de kullanabilirsiniz reshape2:

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

size aynı sonucu verecektir.


8

İlginç bir şekilde, baz R aggregate'in data.frameyöntemi olup, burada teşhir edilmiştir , yukarıda formül arayüzü kullanılır, böylece eksiksizliği,:

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

Agrega'nın data.frame yönteminin daha genel kullanımı:

Biz sağlamak beri

  • data.frameolarak xve
  • a list( data.frameayrıca a list) ' bydır, çünkü bunu dinamik bir şekilde kullanmamız gerektiğinde çok kullanışlıdır, örneğin toplanacak ve toplanacak diğer sütunları kullanmak çok basittir
  • ayrıca özel toplama işlevleri ile

Örneğin şöyle:

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

(Version - ) develsürümü ile, işlevi birden çok sütunadplyr‘0.8.99.9000’summariseacross

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

Veri toplama için daha esnek ve daha hızlı bir yaklaşım için , CRAN'da collapbulunan collapse R paketindeki işleve bakın :

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

Not : mean, maxvb. Gibi temel işlevleri kullanabilirsiniz collap, ancak fmean, fmaxvb. C ++ tabanlı gruplandırılmış işlevlerdir. İle Çökme paketinde önemli ölçüde daha hızlı olan (yani, büyük veri toplamalarındaki performans data.table ile aynıdır ve daha fazla esneklik sağlar. bu hızlı gruplanmış işlevler olmadan da kullanılabilir collap).

Not2 : collapAyrıca, custombağımsız değişkeni kullanarak yapabileceğiniz esnek çok türlü veri toplamayı da destekler , ancak sayısal ve sayısal olmayan sütunlara yarı otomatik bir şekilde de işlevler uygulayabilirsiniz:

# 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

Partiye geç, ama son zamanlarda özet istatistikleri almak için başka bir yol buldu.

library(psych) describe(data)

Çıktı: ortalama, min, maks, standart sapma, n, standart hata, basıklık, çarpıklık, medyan ve her değişken için aralık.


Soru, gruba göre toplama yapmakla ilgili , ancak gruba göredescribe hiçbir şey yapmıyor ...
Gregor Thomas

describe.by(column, group = grouped_column)değerleri gruplandıracak
britt

4
Peki, o zaman cevaba koy! Bir yorumda saklamayın!
Gregor Thomas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.