2013-03-07 18 views
6

Mam pozornie proste pytanie, ale nie mogę wymyślić, jak uzyskać dokładnie to, co chcę.Jak liczyć wystąpienia współczynnika w kilku kolumnach, grupując według jednej kolumny?

Moje dane wygląda następująco:

 Job  C/C++  Java  Python 
    Student  FALSE  TRUE  FALSE 
Developer  TRUE  TRUE  TRUE 
Developer  TRUE  TRUE  FALSE 
Sysadmin  TRUE FALSE  FALSE 
    Student  FALSE  TRUE  TRUE 

chciałbym grupy przez „Job” kolumny i policzyć TRUE s w każdej kolumnie. Mój sygnał wyjściowy będzie wyglądać następująco:

 Job  C/C++  Java  Python 
    Student   0  2   1 
Developer   2  2   1 
Sysadmin   1  0   0 

Każda pomoc będzie mile widziana.

+1

Czy mógłbyś opisać, co dotychczas wypróbowałeś w swoim pytaniu? – Caramiriel

Odpowiedz

7

alternatywne plyr i data.table rozwiązania:

data.table:

require(data.table) 
tmp.dt <- data.table(temp, key="Job") 
tmp.dt[, lapply(.SD, sum), by=Job] 

#   Job C.C.. Java Python 
# 1: Developer  2 2  1 
# 2: Student  0 2  1 
# 3: Sysadmin  1 0  0 

plyr:

require(plyr) 
ddply(temp, .(Job), function(x) colSums(x[-1])) 

#   Job C.C.. Java Python 
# 1 Developer  2 2  1 
# 2 Student  0 2  1 
# 3 Sysadmin  1 0  0 

Edit: Jeśli zamiast PRAWDA/FAŁSZ, masz policzyć liczbę Newbie „s, a następnie:

Z data.table:

require(data.table) 
tmp.dt <- data.table(temp, key="Job") 
tmp.dt[, lapply(.SD, function(x) sum(x == "Newbie")), by=Job] 

Z plyr:

require(plyr) 
ddply(temp, .(Job), function(x) colSums(x[-1] == "Newbie")) 
+0

Ja zdecydowanie wolę odpowiedź data.table tutaj, ale miło jest mieć alternatywy. – A5C1D2H2I1M1N2O1R2T1

+0

To bardzo miłe i myślę, że wykorzystam to rozwiązanie. Inne pytanie: co byś zrobił, gdyby dane nie były TRUE/FALSE, a zamiast tego arbitralny ciąg znaków. Tak jakbym był zainteresowany liczeniem liczby "nowicjuszy" w Pythonie? – user2145843

+1

@ user2145843, witamy w Stack Overflow. Zwróć uwagę na przycisk "Zadaj pytanie", który kliknąłbyś, aby zadać pierwsze pytanie. Twoje pytanie uzupełniające w tym komentarzu jest na tyle różne, że można je uznać za inne pytanie. Zanim jednak zadasz nowe pytanie, pamiętaj, aby * wyszukać * w przypadku podobnych pytań. – A5C1D2H2I1M1N2O1R2T1

9

Zakładając, że data.frame nazywa się "temp", wystarczy użyć aggregate:

aggregate(. ~ Job, temp, sum) 
#   Job C.C.. Java Python 
# 1 Developer  2 2  1 
# 2 Student  0 2  1 
# 3 Sysadmin  1 0  0 

Logika jest, że TRUE i FALSE przyrównać do wartości numerycznych "1" i "0", a więc po agregowaniu możesz po prostu użyć sum.


A, aby dodać rozwiązanie „tidyverse” dla kompletności:

library(tidyverse) 
temp %>% 
    group_by(Job) %>% 
    summarise_all(sum) 
# # A tibble: 3 x 4 
# Job  C.C.. Java Python 
# <chr>  <int> <int> <int> 
# 1 Developer  2  2  1 
# 2 Student  0  2  1 
# 3 Sysadmin  1  0  0 

Oto dane w formacie, który jest łatwy do kopiowania i wklejania. Zostało to uzyskane przy użyciu dput(your-actual-data-frame-name) i jest to, co powinieneś używać w przyszłości, publikując pytania R do Stack Overflow.

temp <- structure(list(Job = c("Student", "Developer", "Developer", "Sysadmin", 
      "Student"), C.C.. = c(FALSE, TRUE, TRUE, TRUE, FALSE), Java = c(TRUE, 
      TRUE, TRUE, FALSE, TRUE), Python = c(FALSE, TRUE, FALSE, FALSE, TRUE)), 
      .Names = c("Job", "C.C..", "Java", "Python"), class = "data.frame", 
      row.names = c(NA, -5L)) 
Powiązane problemy