2016-06-01 6 views
2

Ich habe einen Datenrahmen wo jeder Artikel hat drei Kategorien (a, b, c) und eine numerische Antwort für jede Kategorie wird aufgezeichnet (entweder 0 oder 1). Ich möchte eine neue Spalte abhängig von den Zeilen in der Spalte Antwort erstellen. Dies ist, wie meine Datenrahmen wie folgt aussehen:Wie schreibe ich eine neue Spalte, die von gruppierten Zeilen in R abhängig ist?

Item  <- rep(c(1:3), each=3) 
Option <- rep(c('a','b','c'), times=3) 
Answer <- c(1,1,0,1,0,1,1,1,1) 
df  <- data.frame(Item, Option, Answer) 


    Item Option Answer 
1 1  a  1 
2 1  b  1 
3 1  c  0 
4 2  a  0 
5 2  b  0 
6 2  c  1 
7 3  a  1 
8 3  b  1 
9 3  c  1 

Was benötigt wird: wenn die drei Kategorien in der Option Spalte 1 sind, die New Spalte einen 1. In jedem anderen Fall erhalten soll, die Säule sollte ein 0. Die gewünschte Ausgabe sollte wie folgt aussehen:

Item Option Answer New 
1 1  a  1 0 
2 1  b  1 0 
3 1  c  0 0 
4 2  a  0 0 
5 2  b  0 0 
6 2  c  1 0 
7 3  a  1 1 
8 3  b  1 1 
9 3  c  1 1 

ich habe versucht, dies zu erreichen, ohne eine Schleife, aber ich blieb stecken, weil ich weiß nicht, wie ein neues Spalte kontingente auf einem machen Gruppe von Zeilen, nicht nur als ein eins. Ich habe versucht this solution, aber es funktioniert nicht, wenn die Zeilen nicht in Paaren gruppiert sind.

Haben Sie Vorschläge? Vielen Dank!

+0

Mit der gleichen Menge an "Option" s für jedes "Item" verwendet, könnte man Betrachten Sie das Speichern Ihrer Daten in einer "Matrix" wie "xtabs (Antwort ~ Element + Option, df)" (und mit "Antwort" 0/1, Sie könnten speichern es als eine spärliche "Matrix"). Dann könnten Sie beispielsweise 'colSums' verwenden, um" 1 "s zu zählen –

Antwort

4

Dies sollte funktionieren:

df %>% 
    group_by(Item)%>% 
    mutate(New = as.numeric(all(as.logical(Answer)))) 
+0

Danke! Aber wenn ich diesen Befehl ausführe, erstellt er eine neue Spalte mit allen 0 (sogar für den Punkt 3, der eine 1 sein sollte) und gibt mir eine Warnung: * In allen (Answer): Argument des Typs 'double' zu logisch * . Irgendeine Idee, was schief läuft? – Sol

+0

Es nutzt die Tatsache aus, dass R "TRUE" als "1" und "FALSE" als "0" darstellt, aber abhängig von der logischen Zwangsführung. Warnungen hindern es nicht daran zu arbeiten (Warnungen sind keine Fehler), aber wenn Sie sie vermeiden wollen, zwingen Sie entweder explizit, dh 'as.numeric (all (as.logical (Answer))) oder testen Sie explizit, dh' as.numeric (alle (Antwort == 1)) '. So oder so, 'all' benötigt logische Werte zur Auswertung. – alistaire

+0

@alistaire: danke! Ich kann die Warnung loswerden, indem ich ** Antwort ** in logisch umwandeln, aber es ist immer noch der Fall, dass die Lösung nicht funktioniert und die neue Spalte nur 0s anzeigt. – Sol

3

data.table

DT <- data.table(Item, Option, Answer) 
DT[, Index := as.numeric(all(as.logical(Answer))), by= Item] 
DT 

    Item Option Answer Index 
1: 1  a  1  0 
2: 1  b  1  0 
3: 1  c  0  0 
4: 2  a  1  0 
5: 2  b  0  0 
6: 2  c  1  0 
7: 3  a  1  1 
8: 3  b  1  1 
9: 3  c  1  1 
2

verwenden oder nur base R

df$Index <- with(df, +(ave(!!Answer, Item, FUN = all))) 
df$Index 
#[1] 0 0 0 0 0 0 1 1 1