2016-04-23 12 views
0

ich Bewertungen von Bildern durch mehrere Rater haben:R: Aggregate Datenrahmen, wenn die Spalte weniger als 3 Nullen hat, zurückgeben sonst Null

data <- as.data.frame(matrix(c(rep(1,6),rep(2,6),rep(1:6,2), 
           0,2,1,0,1,0,0,0,3,0,0,0),12,3)) 
colnames(data) <- c("image", "rater", "rating") 
print(data) 

# image rater rating 
# 1  1  1  0 
# 2  1  2  2 
# 3  1  3  1 
# 4  1  4  0 
# 5  1  5  1 
# 6  1  6  0 
# 7  2  1  0 
# 8  2  2  0 
# 9  2  3  3 
# 10  2  4  0 
# 11  2  5  0 
# 12  2  6  0 

Ich möchte aggregieren (mean) Bewertungen von Bildern, aber nur, wenn es weniger als 3 Bewertungen für ein bestimmtes Bild. Andernfalls (= wenn 3 Nullen oder mehr vorhanden sind), sollte die aggregierte Bewertung Null sein. Und das Zählen von Nullen sollte nur für die Rater 1-5 sein.

Also für die obigen Daten:

# image rating 
# 1  1  0.8 
# 2  2  0.0 

Für Bild 1 Bewertungen aggregiert werden, da die dritte Null 6. Bild 2 ist die aggregierte Bewertung ist Null rater gehört, weil es mehr als zwei Nullen sind.

Darüber hinaus möchte ich die Aggregation berücksichtigen a) nur die ersten 5 Bewertungen für jedes Bild, und b) nur positive Bewertungen.

kann ich die letzten 2 Bedingungen mit aggregate verwalten:

aggregate(rating ~ image, data = data[data$rater <= 5 & data$rating != 0,], mean) 

# Result: 
# image rating 
# 1  1 1.333333 
# 2  2 3.000000 

Aber ich kann nicht die erste Bedingung herauszufinden.

korrekte Ergebnisse sollte sein:

# image rating 
# 1  1 1.333333 
# 2  2 0.000000 

Kann jemand bitte helfen? Vielen Dank.

+1

Versuchen Sie etwas wie 'Bibliothek (data.table); setDT (data) [, if (sum (bewertung [rater < 6] == 0) > 2) 0 else mean (rating [rating! = 0]), durch = image] 'vielleicht. Oder' library (dplyr); daten%>% group_by (image)%>% summary (rating = ifelse (sum [rating < 6] == 0) > 2, 0, mean (rating [rating! = 0]))). "was immer du bevorzugst. –

+0

@DavidArenburg Siehe meine Antwort im Geiste der Erweiterung Basis R verwenden. :) – lmo

Antwort

1

Hier ist eine schöne Methode Base R mit:

data$this <- ave(data$rating, data$image, 
       FUN=function(i) if(sum(i[1:5] > 0) > 2) mean(i[1:5]) else 0) 

I i[1:5] verwenden, um jedes Bild der Teilmenge, so dass, wenn Sie weniger als 5 Rater für ein Bild haben, erhalten Sie eine Fehlermeldung erhalten. Dies gibt den Mittelwert für jede Gruppe zurück, falls dies von Interesse ist. Natürlich können Sie dieselbe Funktion verwenden, um die von Ihnen erwähnte Aggregationstabelle zu erstellen:

aggregate(data$rating, data["image"], 
        FUN=function(i) if(sum(i[1:5] > 0) > 2) mean(i[1:5]) else 0)