Her gruptaki satır sayısını sayın


121

Bir veri çerçevem ​​var ve her gruptaki satır sayısını saymak istiyorum. aggregateVerileri toplamak için işlevi düzenli olarak aşağıdaki gibi kullanıyorum:

df2 <- aggregate(x ~ Year + Month, data = df1, sum)

Şimdi, gözlemleri saymak istiyorum ama uygun argümanı bulamıyorum FUN. Sezgisel olarak, aşağıdaki gibi olacağını düşündüm:

df2 <- aggregate(x ~ Year + Month, data = df1, count)

Ama böyle bir şans yok.

Herhangi bir fikir?


Bazı oyuncak verileri:

set.seed(2)
df1 <- data.frame(x = 1:20,
                  Year = sample(2012:2014, 20, replace = TRUE),
                  Month = sample(month.abb[1:3], 20, replace = TRUE))

17
nrow, NROW, length...
Joshua Ulrich

15
Bu soruyu bir şeyleri saymanın eğlenceli bir yolunu sormak olarak okumaya devam ediyorum (sanırım pek çok kaçış yolunun aksine).
Hong Ooi

6
@JoshuaUlrich: nrowBenim için iş ama olmadı NROWve lengthçalıştı ince. +1
Prolix

Yanıtlar:


69

Mevcut en iyi uygulama (tidyverse):

require(dplyr)
df1 %>% count(Year, Month)

Bir değişkeni toplayıp saymanın da bir yolu var mı (toplamadaki 2 işlev gibi: ortalama + sayım)? Bir sütunun ortalamasını ve diğer sütundaki aynı değer için satır sayısını almam gerekiyor
sop

1
Ben cbindsonuçları aggregate(Sepal.Length ~ Species, iris, mean)veaggregate(Sepal.Length ~ Species, iris, length)
geotheory

Bunu yaptım, ancak görünüşe göre toplanan hariç her sütunda 2 kez alıyorum; bu yüzden onları birleştirme yaptım ve sorun yok gibi görünüyor
sop

6
Bilmiyorum ama bu da yararlı olabilir ...df %>% group_by(group, variable) %>% mutate(count = n())
Manoj Kumar

1
Evet dplyr şu anda en iyi uygulamadır.
geotheory

67

@ Joshua'nın önerisini takiben, dfveri çerçevenizdeki gözlemlerin sayısını Year= 2007 ve Month= Kasım (sütun olduklarını varsayarak) saymanın bir yolu :

nrow(df[,df$YEAR == 2007 & df$Month == "Nov"])

ve aggregate@GregSnow ile:

aggregate(x ~ Year + Month, data = df, FUN = length)

47

dplyrpaket bunu count/ tallykomutları veya n()işlevi ile yapar :

İlk olarak, bazı veriler:

df <- data.frame(x = rep(1:6, rep(c(1, 2, 3), 2)), year = 1993:2004, month = c(1, 1:11))

Şimdi sayı:

library(dplyr)
count(df, year, month)
#piping
df %>% count(year, month)

Ayrıca borulama ve n()fonksiyon ile biraz daha uzun bir versiyon da kullanabiliriz :

df %>% 
  group_by(year, month) %>%
  summarise(number = n())

veya tallyişlev:

df %>% 
  group_by(year, month) %>%
  tally()

37

data.tableÇözümü olmayan eski bir soru . İşte başlıyor ...

kullanma .N

library(data.table)
DT <- data.table(df)
DT[, .N, by = list(year, month)]

1
standart günümüzde bir data.frame .()yerine kullanmak list()ve setDT()data.table'a dönüştürmek için kullanılır. Yani tek adımda setDT(df)[, .N, by = .(year, month)].
sindri_baldur

23

Kullanılabilecek basit seçenek, size alt kümedeki vektörün uzunluğunu verecek aggregateolan lengthişlevdir. Bazen biraz daha sağlam kullanmaktır function(x) sum( !is.na(x) ).


18

CountHer satır için 1 değerine sahip yeni bir değişken oluşturun :

df1["Count"] <-1

Ardından, Countsütuna göre toplayarak veri çerçevesini toplayın :

df2 <- aggregate(df1[c("Count")], by=list(Year=df1$Year, Month=df1$Month), FUN=sum, na.rm=TRUE)

Eğer varsayılan kullanıyorsanız Sadece nota, olmayan formül yöntem aggregate, her değişken yeniden adlandırmak için gerek yoktur by=gibi list(year=df1$year)vb bir data.framebir olduğunu listzaten aggregate(df1[c("Count")], by=df1[c("Year", "Month")], FUN=sum, na.rm=TRUE)çalışacaktır.
posta

17

Bir alternatif aggregate(), bu durumda fonksiyonu olacaktır table()ile as.data.frame()de yıl ve Ay kombinasyonları sıfır oluşumuyla ilişkili olan işaret ettiği,

df<-data.frame(x=rep(1:6,rep(c(1,2,3),2)),year=1993:2004,month=c(1,1:11))

myAns<-as.data.frame(table(df[,c("year","month")]))

Ve sıfır oluşan kombinasyonlar olmadan

myAns[which(myAns$Freq>0),]

7

Verilerde eksik olan ay-yıllar için 0 sayım eklemek isterseniz biraz tablesihir kullanabilirsiniz .

data.frame(with(df1, table(Year, Month)))

Örneğin, df1 sorusundaki oyuncak data.frame, Ocak 2014'e ait herhangi bir gözlem içermiyor.

df1
    x Year Month
1   1 2012   Feb
2   2 2014   Feb
3   3 2013   Mar
4   4 2012   Jan
5   5 2014   Feb
6   6 2014   Feb
7   7 2012   Jan
8   8 2014   Feb
9   9 2013   Mar
10 10 2013   Jan
11 11 2013   Jan
12 12 2012   Jan
13 13 2014   Mar
14 14 2012   Mar
15 15 2013   Feb
16 16 2014   Feb
17 17 2014   Mar
18 18 2012   Jan
19 19 2013   Mar
20 20 2012   Jan

Temel R aggregateişlevi, Ocak 2014 için bir gözlem döndürmez.

aggregate(x ~ Year + Month, data = df1, FUN = length)
  Year Month x
1 2012   Feb 1
2 2013   Feb 1
3 2014   Feb 5
4 2012   Jan 5
5 2013   Jan 2
6 2012   Mar 1
7 2013   Mar 3
8 2014   Mar 2

Sayım olarak 0 ile bu ay-yıl için bir gözlem yapmak isterseniz, yukarıdaki kod tüm ay-yıl kombinasyonları için sayıları olan bir data.frame döndürecektir:

data.frame(with(df1, table(Year, Month)))
  Year Month Freq
1 2012   Feb    1
2 2013   Feb    1
3 2014   Feb    5
4 2012   Jan    5
5 2013   Jan    2
6 2014   Jan    0
7 2012   Mar    1
8 2013   Mar    3
9 2014   Mar    2

5

Toplamalarım için genellikle ortalama ve "bu grubun ne kadar büyük olduğunu" (diğer adıyla uzunluk) görmek isterim. Bu, bu tür durumlar için benim kullanışlı pasajım;

agg.mean <- aggregate(columnToMean ~ columnToAggregateOn1*columnToAggregateOn2, yourDataFrame, FUN="mean")
agg.count <- aggregate(columnToMean ~ columnToAggregateOn1*columnToAggregateOn2, yourDataFrame, FUN="length")
aggcount <- agg.count$columnToMean
agg <- cbind(aggcount, agg.mean)

5

bir sqldfpaketi kullanarak çözüm :

library(sqldf)
sqldf("SELECT Year, Month, COUNT(*) as Freq
       FROM df1
       GROUP BY Year, Month")

1

@Ben cevabı düşünüldüğünde, sütun df1içermiyorsa R hata verir x. Ancak şunlarla zarif bir şekilde çözülebilir paste:

aggregate(paste(Year, Month) ~ Year + Month, data = df1, FUN = NROW)

Benzer şekilde, gruplamada ikiden fazla değişken kullanılıyorsa genelleştirilebilir:

aggregate(paste(Year, Month, Day) ~ Year + Month + Day, data = df1, FUN = NROW)

0

Gerekli toplamanın bir listesini oluşturacak byişlevleri kullanabilirsiniz by(df1$Year, df1$Month, count).

Çıktı şöyle görünecek:

df1$Month: Feb
     x freq
1 2012    1
2 2013    1
3 2014    5
--------------------------------------------------------------- 
df1$Month: Jan
     x freq
1 2012    5
2 2013    2
--------------------------------------------------------------- 
df1$Month: Mar
     x freq
1 2012    1
2 2013    3
3 2014    2
> 

0

Burada zaten çok sayıda harika cevap var, ancak orijinal veri kümesine o satırın tekrarlanma sayısını içeren yeni bir sütun eklemek isteyenler için 1 seçenek daha eklemek istedim.

df1$counts <- sapply(X = paste(df1$Year, df1$Month), 
                     FUN = function(x) { sum(paste(df1$Year, df1$Month) == x) })

Aynı şey, yukarıdaki yanıtlardan herhangi biri merge()işlevle birleştirilerek de gerçekleştirilebilir .


0

Yukarıdaki toplu çözümleri deniyorsanız ve şu hatayı alıyorsanız:

değişken için geçersiz tür (liste)

Tarih veya tarih ve saat damgaları kullandığınız için, değişkenler üzerinde as.character'ı kullanmayı deneyin:

aggregate(x ~ as.character(Year) + Month, data = df, FUN = length)

Değişkenlerin birinde veya her ikisinde.

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.