2012-07-20 19 views
18

Wydaje się, że taki prosty problem, ale byłem ciągnąc moje włosy starając się uzyskać to do pracy:Kruszywo (liczba) wiersze spełniające warunek, grupa o unikalnych wartościach

Biorąc pod uwagę to rama dane identyfikujące interakcje id mieli z contact którzy są pogrupowane według 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 

jak wiele kontaktów, gdzie tam unique(data$contactGrp) z relpos=1 i maxpos>1?

Oczekiwany wynik byłby:

1 west 1 
2 south 1 
3 east 0 

niewielki podzbiór wierszy Próbowałem:

  • aggregate(data, by=list('contactGrp'), FUN=count) daje błąd, bez filtrowania
  • użyciu data.table wydaje się wymagać klucza, który nie jest unikalny w tych danych ...
  • ddply(data,"contactGrp",summarise,count=???) nie wiesz, której funkcji użyć, aby wypełnić count kolumna
  • ddply(subset(data,maxpos>1 & relpos==0), c('contactGrp'), function(df)count(df$relpos)) działa, ale daje mi dodatkową kolumnę x i czuje się jakbym to nadmiernie skomplikowane ...

SQL byłoby proste: Select contactGrp, count(*) as cnt from data where … Group by contactGrp ale im próbuje dowiedzieć R

+0

Myślę, że chodziło o 'zachód 2, wschód 0, południe 0' o oczekiwane rezultaty. – joran

+0

faktycznie relpos = 1. Ale tak dla relpos = 0 oczekiwany wynik jest błędny ... –

+0

Gah! Masz rację, przepraszam. Jest wcześnie rano, gdzie jestem. :) – joran

Odpowiedz

19

myślę, że to jest ddply wersja szukasz:

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

Dzięki. Niektóre z tych składni wydają mi się nieco niejasne: notacja kolumny.(), Mogąca odwoływać się do _columnName_ [condition] jako parametru do funkcji length. Przypuszczam, że mam trochę do czytania ... –

+0

@LukasGrebe Przepraszam, notacja ".()" Jest moim nawykiem, ale nie jest bezwzględnie konieczna. Możesz także określić zmienne grupujące z czymś takim jak 'c (" contactGrp ")'. – joran

+0

bez problemu. dowiedziałem się czegoś :) –

10

Oto inne podejście:

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

A oto data.table rozwiązanie:

> 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

Twoja pierwsza próba linia z kruszywem nie działa, ponieważ nie ma funkcji count. Miałeś na myśli length. Wszystko, co musisz zrobić, to wykonać z warunkowym wyborem danych dla relpos i maxpos, a także wybrać zmienną obojętną, aby uzyskać liczbę (nie ma znaczenia). Niemniej jednak, zamiast używać elastycznych poleceń agregujących różnego rodzaju, polecenie zbudowane w table zostało zaprojektowane właśnie w tym celu.

with(data[data$relpos == 1 & data$maxpos > 1,], table(contactGrp)) 
Powiązane problemy