2013-03-07 11 views
6

Ich habe eine scheinbar einfache Frage, aber ich kann nicht herausfinden, wie man genau das bekommt, was ich will.Wie zähle ich das Vorkommen eines Faktors in mehreren Spalten, gruppiert nach einer Spalte?

Meine Daten sieht wie folgt aus:

 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 

ich von der „Job“ Spalte Gruppe möchte und die Anzahl der TRUE s in jeder Spalte zählen. Meine gewünschte Ausgabe würde so aussehen:

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

Jede Hilfe würde sehr geschätzt werden.

+1

Können Sie beschreiben, was Sie bisher in Ihrer Frage versucht haben? – Caramiriel

Antwort

7

Alternative plyrdata.table und Lösungen:

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: Wenn statt WAHR/FALSCH, haben Sie die Anzahl der Newbie ‚s zu zählen, dann:

Mit data.table:

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

Mit plyr:

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

Ich bevorzuge die data.table Antwort hier, aber es ist schön, Alternativen zu haben. – A5C1D2H2I1M1N2O1R2T1

+0

Das ist sehr nett und ich denke, dass ich diese Lösung verwenden werde. Eine weitere Frage: Was würden Sie tun, wenn die Daten nicht WAHR/FALSCH wären, sondern eine beliebige Zeichenfolge? Wie wenn ich daran interessiert wäre, die Anzahl der "Newbie" in Python zu zählen? – user2145843

+1

@ user2145843, Willkommen bei Stack Overflow. Bitte beachten Sie die Schaltfläche "Frage stellen", auf die Sie geklickt hätten, um Ihre erste Frage zu stellen. Ihre Folgefrage in diesem Kommentar ist anders genug, um als eine andere Frage betrachtet zu werden. Aber stellen Sie sicher, dass Sie * nach ähnlichen Fragen suchen, bevor Sie eine neue Frage stellen. – A5C1D2H2I1M1N2O1R2T1

9

Ihren data.frame Unter der Annahme, "temp" genannt, nur aggregate verwenden:

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

Die Logik ist, dass TRUE und FALSE auf numerische Werte von "1" und "0" gleichsetzen, so Sie können einfach sum bei der Aggregation verwenden.


Und die "tidyverse" Lösung für die Vollständigkeit hinzuzufügen:

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 

hier Ihre Daten in einem Format, das leicht zu kopieren und einfügen ist. Dies wurde mithilfe von dput(your-actual-data-frame-name) erreicht und sollte in Zukunft verwendet werden, wenn Sie R-Fragen an Stack Overflow senden.

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)) 
Verwandte Themen