2012-07-20 13 views
18

Sembra un semplice problema così, eppure sono stato tirando fuori i miei capelli cercando di arrivare a questo lavoro:Aggregate (conteggio) le righe che corrispondono a una condizione, gruppo da valori unici

Dato questo frame di dati di identificazione le interazioni id avevano con contact che è raggruppato per contactGrp,

head(data) 
    id    sesTs contact contactGrp relpos maxpos 
1 6849 2012-06-25 15:58:34 peter  west 0.000000  3 
2 6849 2012-06-25 18:24:49 sarah  south 0.500000  3 
3 6849 2012-06-27 00:13:30 sarah  south 1.000000  3 
4 1235 2012-06-29 17:49:35 peter  west 0.000000  2 
5 1235 2012-06-29 23:56:35 peter  west 1.000000  2 
6 5893 2012-06-30 22:21:33 carl   east 0.000000  1 

quanti contatti dove lì per unique(data$contactGrp) con relpos=1 e maxpos>1?

Un risultato atteso sarebbe:

1 west 1 
2 south 1 
3 east 0 

Un piccolo sottoinsieme di linee ho provato:

  • aggregate(data, by=list('contactGrp'), FUN=count) produce un errore, nessun filtro
  • utilizzando data.table sembra richiedere una chiave, che non è univoco in questi dati ...
  • ddply(data,"contactGrp",summarise,count=???) non è sicuro quale funzione utilizzare per riempire il count colonna
  • ddply(subset(data,maxpos>1 & relpos==0), c('contactGrp'), function(df)count(df$relpos)) opere, ma mi dà una colonna in più x e ci si sente come se fossi troppo complicata è ...

SQL sarebbe stato facile: Select contactGrp, count(*) as cnt from data where … Group by contactGrp ma im cercando di imparare R

+0

Penso che intendessi "ovest 2, est 0, sud 0" per i risultati attesi. – joran

+0

in realtà relpos = 1. Ma sì per relpos = 0 il risultato atteso è elencato in modo errato ... –

+0

Gah! Hai ragione, mi dispiace. È mattina presto dove sono. :) – joran

risposta

19

Penso che questo sia la versione ddply che stai cercando:

ddply(sessions,.(contactGrp), 
     summarise, 
     count = length(contact[relpos == 0 & maxpos > 1])) 
+0

Grazie. Alcune di questa sintassi mi sembrano un po 'oscure: la notazione della colonna.(), Potendo riferirsi a _columnName_ [condition] come parametro alla funzione length. Suppongo di avere qualche lettura da fare ... –

+0

@LukasGrebe Scusa, la notazione '.()' È una mia abitudine, ma non è strettamente necessaria. Puoi anche specificare le variabili di raggruppamento con qualcosa come 'c (" contactGrp ")'. – joran

+0

nessun problema. imparato qualcosa :) –

10

Ecco un altro approccio:

a <- data.frame(id=1:10, contact=sample(c("peter", "sahrah"), 10, T), contactGrp=sample(c("west", "east"), 10, T), relpos=sample(0:1, 10, T), maxpos=runif(10, 0,10)) 

library(sqldf) 
sqldf("Select contactGrp, count(*) as cnt from a where relpos=0 and maxpos > 1 Group by contactGrp") 
    contactGrp cnt 
1  east 3 
2  west 1 
22

E qui è la soluzione data.table:

> library(data.table) 
> dt <- data.table(sessions) 
> dt[, length(contact[relpos == 0 & maxpos > 1]), by = contactGrp] 
    contactGrp V1 
[1,]  west 2 
[2,]  south 0 
[3,]  east 0 

> dt[, length(contact[relpos == 1 & maxpos > 1]), by = contactGrp] 
    contactGrp V1 
[1,]  west 1 
[2,]  south 1 
[3,]  east 0 
10

La prima linea tentato con inerti non funziona perché non v'è alcuna funzione count. Intendevi length. Tutto quello che dovevi fare era eseguirlo con la selezione dei dati condizionali per relpos e maxpos, e anche selezionare una variabile dummy per ottenere il conteggio di (non importa quale). Tuttavia, invece di utilizzare comandi di aggregazione flessibili di vario tipo, il comando integrato table è progettato proprio per questo.

with(data[data$relpos == 1 & data$maxpos > 1,], table(contactGrp)) 
Problemi correlati