2015-05-13 6 views
5

Ho un frame di dati con due colonne. Voglio aggiungere altre due colonne al set di dati con i conteggi basati sugli aggregati.Aggregating in R

df <- structure(list(ID = c(1045937900, 1045937900), 
SMS.Type = c("DF1", "WCB14"), 
SMS.Date = c("12/02/2015 19:51", "13/02/2015 08:38"), 
Reply.Date = c("", "13/02/2015 09:52") 
), row.names = 4286:4287, class = "data.frame") 

Voglio contare semplicemente il numero di istanze di SMS.Type e Reply.Date dove non c'è nulla. Quindi nell'esempio del giocattolo qui sotto, genererò il 2 per SMS.Type e 1 per Reply.Date

Poi voglio aggiungere questo al frame di dati come conteggi totali (sono consapevole che verranno duplicati per il numero di le righe di dati originale, ma questo è ok)

ho giocato in giro con funzione di aggregazione e contare, ma senza alcun risultato

mytempdf <-aggregate(cbind(testtrain$SMS.Type,testtrain$Response.option)~testtrain$ID, 
        train, 
        function(x) length(unique(which(!is.na(x))))) 

mytempdf <- aggregate(testtrain$Reply.Date~testtrain$ID, 
        testtrain, 
        function(x) length(which(!is.na(x)))) 

chiunque può aiutare?

Grazie per il vostro tempo

risposta

5

Utilizzando data.table si potrebbe fare (ho aggiunto un vero e proprio NA ai dati originali). Non sono nemmeno sicuro se davvero stai cercando length(unique()) o solo length?

library(data.table) 
cols <- c("SMS.Type", "Reply.Date") 
setDT(df)[, paste0(cols, ".count") := 
        lapply(.SD, function(x) length(unique(na.omit(x)))), 
        .SDcols = cols, 
      by = ID] 
#   ID SMS.Type   SMS.Date  Reply.Date SMS.Type.count Reply.Date.count 
# 1: 1045937900  DF1 12/02/2015 19:51    NA    2    1 
# 2: 1045937900 WCB14 13/02/2015 08:38 13/02/2015 09:52    2    1 

Nella versione devel (v> = 1.9.5) si potrebbe anche usare la funzione uniqueN


Spiegazione

Si tratta di una soluzione generale che funziona su qualsiasi numero di colonne desiderate Tutto quello che devi fare è inserire i nomi delle colonne in cols.

  1. lapply(.SD, sta chiamando una determinata funzione sopra le colonne specificate nella .SDcols = cols
  2. paste0(cols, ".count") crea nuovi nomi delle colonne, mentre l'aggiunta count ai nomi delle colonne di cui cols
  3. := esegue di assegnazione con riferimento significato, aggiornamenti le colonne appena create con l'output di lapply(.SD,sul posto
  4. by argomento è specificare le colonne aggregatore
+0

Ciao David, Grazie per avermi fatto conoscere data.table ... Puoi spiegare cosa ogni riga sta facendo da il SetDT in poi se ne hai il tempo. Per rispondere alla tua domanda, stavo usando la lunghezza (unique()) per provare e contare i valori in modo univoco nelle colonne –

+0

Ho aggiunto una spiegazione. –

+1

Grazie mille per la risposta –

1

Dopo aver convertito i stringhe vuote per AN:

library(dplyr) 
mutate(df, SMS.Type.count = sum(!is.na(SMS.Type)), 
      Reply.Date.count = sum(!is.na(Reply.Date))) 
+1

OP vuole comunque contare voci uniche. –