2013-04-23 10 views
10

ho dati in R che assomiglia a questo:R: Count valori unici per categoria

Cnty Yr Plt  Spp DBH Ht Age 
1 185 1999 20001 Bitternut 8.0 54 47 
2 185 1999 20001 Bitternut 7.2 55 50 
3 31 1999 20001 Pignut 7.4 71 60 
4 31 1999 20001 Pignut 11.4 85 114 
5 189 1999 20001  WO 14.5 80 82 
6 189 1999 20001  WO 12.1 72 79 

Vorrei conoscere la quantità di specie uniche (SPP) in ogni regione (Cnty). "unique (dfname $ Spp)" mi dà un conteggio totale di specie uniche nel frame di dati, ma mi piacerebbe per contea.

Qualsiasi aiuto è apprezzato! Scusa per la strana formattazione, questa è la mia prima domanda in assoluto su SO.

Grazie.

+0

Benvenuti a SO. Condividere di più su cosa hai provato e dove stai incontrando problemi daranno risposte migliori. Ma, per iniziare, funzioni come 'aggregate' e' tapply' sono utili. ricorda di guardare il testo di aiuto da una funzione usando '? aggregate'. – Justin

risposta

2

Come ha detto Justin aggregato è probabilmente quello che vuoi. Se chiami il tuo frame di dati foo, allora il seguente dovrebbe darti quello che vuoi, cioè il numero di individui per specie supponendo che ogni riga con Butternut rappresenti un individuo unico appartenente alla specie butternut. Nota che ho usato foo $ Age per calcolare la lunghezza del vettore, cioè il numero di individui (riga) appartenenti a ciascuna specie, ma è possibile utilizzare foo $ Ht o foo $ DBH ecc

aggregate(foo$Age, by = foo[c('Spp','Cnty')], length) 

Cheers,

Danny

15

Ho cercato di rendere i dati di esempio un po 'più interessanti. Attualmente i dati di esempio hanno solo un "Spp" unico per "Cnty".

set.seed(1) 
mydf <- data.frame(
    Cnty = rep(c("185", "31", "189"), times = c(5, 3, 2)), 
    Yr = c(rep(c("1999", "2000"), times = c(3, 2)), 
     "1999", "1999", "2000", "2000", "2000"), 
    Plt = "20001", 
    Spp = sample(c("Bitternut", "Pignut", "WO"), 10, replace = TRUE), 
    DBH = runif(10, 0, 15) 
) 
mydf 
# Cnty Yr Plt  Spp  DBH 
# 1 185 1999 20001 Bitternut 3.089619 
# 2 185 1999 20001 Pignut 2.648351 
# 3 185 1999 20001 Pignut 10.305343 
# 4 185 2000 20001  WO 5.761556 
# 5 185 2000 20001 Bitternut 11.547621 
# 6 31 1999 20001  WO 7.465489 
# 7 31 1999 20001  WO 10.764278 
# 8 31 2000 20001 Pignut 14.878591 
# 9 189 2000 20001 Pignut 5.700528 
# 10 189 2000 20001 Bitternut 11.661678 

Successivamente, come suggerito, tapply è un buon candidato qui. Combina unique e length per ottenere i dati che stai cercando.

with(mydf, tapply(Spp, Cnty, FUN = function(x) length(unique(x)))) 
# 185 189 31 
# 3 2 2 
with(mydf, tapply(Spp, list(Cnty, Yr), FUN = function(x) length(unique(x)))) 
#  1999 2000 
# 185 2 2 
# 189 NA 2 
# 31  1 1 

Se siete interessati a semplice tabulazione (non di valori unici), allora è possibile esplorare table e ftable:

with(mydf, table(Spp, Cnty)) 
#   Cnty 
# Spp   185 189 31 
# Bitternut 2 1 0 
# Pignut  2 1 1 
# WO   1 0 2 
ftable(mydf, row.vars="Spp", col.vars=c("Cnty", "Yr")) 
#   Cnty 185  189  31  
#   Yr 1999 2000 1999 2000 1999 2000 
# Spp           
# Bitternut   1 1 0 1 0 0 
# Pignut   2 0 0 1 0 1 
# WO    0 1 0 0 2 0 
+0

Ananda: Ottima risposta! Hai correttamente presupposto che esistesse più di un tipo di specie per contea, che è esattamente ciò di cui avevo bisogno. Grazie mille per il tuo aiuto. –

+0

@KlausLouis, felice di sentirlo. Se questa o una delle altre risposte fosse utile, considera l'upvoting e/o [accepting] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) uno di loro. Grazie e benvenuti a Stack Overflow! :) – A5C1D2H2I1M1N2O1R2T1

0
with(mydf, tapply(Spp, list(Cnty, Yr), 
    FUN = function(x) length(unique(x)))) 

interrogazione unica non sta lavorando con grande insieme di dati i significa dati più di 1000k riga.

0

Volevo aggiungere a ciò che menzionava A Handcart e Mohair. Per quelli di voi che vogliono ottenere i risultati del codice qui sotto in un frame di dati (utile in R studio) ...

with(mydf, table(Spp, Cnty)) 
#   Cnty 
# Spp   185 189 31 
# Bitternut 2 1 0 
# Pignut  2 1 1 
# WO   1 0 2 
ftable(mydf, row.vars="Spp", col.vars=c("Cnty", "Yr")) 
#   Cnty 185  189  31  
#   Yr 1999 2000 1999 2000 1999 2000 
# Spp           
# Bitternut   1 1 0 1 0 0 
# Pignut   2 0 0 1 0 1 
# WO    0 1 0 0 2 0 

Avrete bisogno di mettere il modificatore as.data.frame.matrix di fronte del codice in questo modo:

as.data.frame.matrix(with(mydf, table(Spp, Cnty))) 

ero abbastanza nuovo per R, quando mi sono imbattuto in questo post, e mi c'è voluto molto tempo per capirlo, così ho pensato che vorrei condividere.

0

Una soluzione semplice che utilizza l'approccio data.table.

library(data.table) 

output <- setDT(mydf)[ , .(count=.N) , by = .(Spp,Cnty)] 

nel caso in cui si desidera rimodellare l'output in un formato di tabella più bello:

library(tidyr) 

spread(data=a, key =Spp, count) 

# Cnty Bitternut Pignut WO 
# 1: 185   2  2 1 
# 2: 189   1  1 NA 
# 3: 31  NA  1 2 

# or perhaps like this: 

spread(data=a, key =Cnty, count) 

#   Spp 185 189 31 
# 1: Bitternut 2 1 NA 
# 2: Pignut 2 1 1 
# 3:  WO 1 NA 2 
0

ora possiamo usare la funzione di controllo per rendere questo più facile.

tally(group_by(mydf, Spp, Cnty)) 

     Spp Cnty  n 
    <fctr> <fctr> <int> 
1 Bitternut 185  2 
2 Bitternut 189  1 
3 Pignut 185  2 
4 Pignut 189  1 
5 Pignut  31  1 
6  WO 185  1 
7  WO  31  2 
0
set.seed(1) 
mydf <- data.frame(
    Cnty = rep(c("185", "31", "189"), times = c(5, 3, 2)), 
    Yr = c(rep(c("1999", "2000"), times = c(3, 2)), 
     "1999", "1999", "2000", "2000", "2000"), 
    Plt = "20001", 
    Spp = sample(c("Bitternut", "Pignut", "WO"), 10, replace = TRUE), 
    DBH = runif(10, 0, 15) 
) 
mydf 

La funzione dplyr::count() si presenta come una soluzione semplice:

library(dplyr) 
count(mydf, Spp, Cnty) 
# A tibble: 7 x 3 
# Spp  Cnty  n 
# <fct>  <fct> <int> 
# 1 Bitternut 185  2 
# 2 Bitternut 189  1 
# 3 Pignut 185  2 
# 4 Pignut 189  1 
# 5 Pignut 31  1 
# 6 WO  185  1 
# 7 WO  31  2 
Problemi correlati