2016-07-31 254 views
0

Ich bin vor kurzem von STATA + Excel nach R übergegangen. So würde ich schätzen, wenn mir jemand beim Schreiben von effizientem Code helfen könnte. Ich habe mein Bestes versucht, die Antwort zu recherchieren, bevor ich auf SO poste.Bedingte Filterung und Zusammenfassung in R

Hier ist, wie meine Daten wie folgt aussieht:

mydata<-data.frame(sassign$buyer,sassign$purch,sassign$total_) 
str(mydata) 
'data.frame': 50000 obs. of 3 variables: 
$ sassign.buyer : Factor w/ 2 levels "no","yes": 1 1 1 1 1 2 1 1 2 1 ... 
$ sassign.purch : num 10 3 2 1 1 1 1 11 11 1 ... 
$ sassign.total_: num 357 138 172 272 149 113 15 238 418 123 ... 
head(mydata) 
    sassign.buyer sassign.purch sassign.total_ 
1   no   10   357 
2   no    3   138 
3   no    2   172 
4   no    1   272 
5   no    1   149 
6   yes    1   113 

Mein Ziel ist es durchschnittliche Zahl der Käufer mit # bestellt> 1.

So zu finden, hier ist was ich getan habe:

Methode 1: Lange Methode

library(psych) 
check<-as.numeric(mydata$sassign.buyer)-1 
myd<-cbind(mydata,check) 
abcd<-psych::describe(myd[myd$sassign.purch>1,]) 
abcd$mean[4] 

Die Ausgabe, die ich bekommen habe, ist: 0.1031536697, was korrekt ist.

@Sathish: Hier ist, wie Scheck wie folgt aussieht:

head(check) 
0 0 0 0 0 1 

Das ist mein Zweck tat lösen.

Vorteile dieser Methode: Es ist einfach und in der Regel ein Anfänger-Level. Nachteile: Zu viele-- Ich brauche eine zusätzliche Variable (überprüfen). Plus, ich mag diese Methode nicht - es ist zu klobig.

Side Frage: Ich erkannte, dass Funktionen standardmäßig keine höhere Genauigkeit zeigen, obwohl Optionen (Ziffern = 10) festgelegt ist. Zum Beispiel ist hier, was ich von Laufen bekommen: nur

psych::describe(myd[myd$sassign.purch>1,]) 


       vars  n mean  sd median trimmed mad min max range skew 
sassign.buyer* 1 34880 1.10 0.30  1 1.00 0.00 1 2  1 2.61 
sassign.purch  2 34880 5.14 3.48  4 4.73 2.97 2 12 10 0.65 
sassign.total_ 3 34880 227.40 101.12 228 226.13 112.68 30 479 449 0.09 
check    4 34880 0.10 0.30  0 0.00 0.00 0 1  1 2.61 
       kurtosis se 
sassign.buyer*  4.81 0.00 
sassign.purch  -1.05 0.02 
sassign.total_ -0.72 0.54 
check    4.81 0.00 

Es ist, wenn ich

abcd$mean[4] 
lief

Ich habe 0,1031536697

Methode 2: dplyr Mit Ich habe versucht, Rohre und Funktionsaufruf , aber ich gab endlich auf.

Methode 2 | Try1: psych :: beschreiben (dplyr :: Filter (mydata, mydata $ sassign.purch> 1) [, dplyr :: mutieren (as.numeric (mydata $ sassign.buyer) -1)])

Ausgabe:

Error in UseMethod("mutate_") : 
    no applicable method for 'mutate_' applied to an object of class "c('double', 'numeric')" 

Methode 2 | Try2: Unter Verwendung Rohren:

mydata %>% mutate(newcol = as.numeric(sassign.buyer)-1) %>% dplyr::filter(sassign.purch>1) %>% summarise(meanpurch = mean(newcol)) 

Das hat funktioniert, und ich bekam meanpurch 0,1031537 =. Ich bin mir immer noch nicht sicher über Try 1.

Irgendwelche Gedanken, warum das nicht funktioniert?

+0

Bitte versuchen Sie, [diesen Beitrag reproduzierbar zu machen] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). – shayaa

+0

Shayaa - Ich habe den Code bearbeitet..Ich hoffe, dass dies jetzt reproduzierbar ist. Bitte lassen Sie mich wissen ... – watchtower

+1

Sathish, Vielen Dank für Ihre Antwort. Ich habe die Ausgabe von head (check) gepostet. Bitte lassen Sie mich wissen, wenn Sie Fragen haben. – watchtower

Antwort

2

Daten:

> dt 
# sassign.buyer sassign.purch sassign.total_ 
# 1   no   10   357 
# 2   no    3   138 
# 3   no    2   172 
# 4   no    1   272 
# 5   no    1   149 
# 6   yes    1   113 

Anzahl der Käufer mit Käufen von mehr als 1

library(dplyr) 

dt %>% 
    group_by(sassign.buyer) %>% 
    filter(sassign.purch > 1) 

# 
# Source: local data frame [3 x 3] 
# Groups: sassign.buyer [1] 
# 
# sassign.buyer sassign.purch sassign.total_ 
# (chr)   (int)   (int) 
# 1   no   10   357 
# 2   no    3   138 
# 3   no    2   172 

Durchschnittliche Anzahl der Käufer mit Käufen von mehr als 1

dt %>% 
    group_by(sassign.buyer) %>% 
    filter(sassign.purch > 1) %>% 
    summarise(avg_no_buyers_gt_1 = length(sassign.buyer)/ nrow(dt)) 

# Source: local data frame [1 x 2] 
# 
#  sassign.buyer avg_no_buyers_gt_1 
#   (chr)    (dbl) 
# 1   no    0.5 

Wenn keine Gruppierung der Käufer ist erforderlich,

dt %>% 
    filter(sassign.purch > 1) %>% 
    summarise(avg_no_buyers_gt_1 = length(sassign.buyer)/ nrow(dt)) 

# avg_no_buyers_gt_1 
# 1   0.7777778 
+1

Hallo Sathish, Danke für deine Hilfe, aber als ich den letzten Teil des Befehls ausgeführt habe mydata%>% filter (mydata $ sassign.purch> 1)%>% summiere (avg_no_buyers_gt_1 = length (sassign.buyer)/nrow (mydata)), Bekomme ich einen Fehler: "Fehler in UseMethod (" summarise_ "): keine anwendbare Methode für 'summarise_' angewendet auf ein Objekt der Klasse" c ('mts', 'ts') "Könnten Sie mir bitte helfen? – watchtower

+0

Ja, als ich es ohne Gruppierung versuchte ... erhalte ich einen Fehler. Ich benutze meinen Datenrahmen. Ich würde mich über Ihre Hilfe freuen. Ich habe Ihrem Screenshot einen Kommentar hinzugefügt. – watchtower

+1

Versuchen Sie dies: 'mydata%>% filter (sassign.purch> 1)%>% summary (avg_no_buyers_gt_1 = Länge (sassign.buyer)/nrow (mydata)) ' – Sathish

2

Das Finden des Anteils der Fälle, die einer Bedingung entsprechen, ist mit mean() leicht zu tun. Hier ist eine Blog-Post erklärt es: https://drsimonj.svbtle.com/proportionsfrequencies-with-mean-and-booleans, und hier ist ein einfaches Beispiel:

buyer <- c("yes", "yes", "no", "no") 
mean(buyer == "yes") 
#> [1] 0.5 

Also in Ihrem Fall können Sie mean(d$sassign.buyer[d$sassign.purch > 1] == "yes") tun. Hier ist ein Beispiel gearbeitet:

d <- data.frame(
    sassign.buyer = factor(c("yes", "yes", "no", "no")), 
    sassign.purch = c(1, 10, 0, 200) 
) 
mean(d$sassign.buyer[d$sassign.purch > 1] == "yes") 
#> [1] 0.5 

Dieser erhält alle Fälle, in denen d$sassign.purch größer ist han 1, und berechnet dann den Anteil (unter Verwendung von mean()) dieser Fälle, in denen d$sassign.buyer gleich "yes" ist.

+0

Geniales Kommando. Das ist fantastisch. Danke Simon! – watchtower

+0

Simon, danke für deine Hilfe. Ich habe Sathishs Antwort als Antwort markiert, weil ich nach dplyr-Methode gesucht habe. Ich mag deine Methode, weil sie extrem schnell und effizient ist. Ich hoffe es stört dich nicht. Ich dachte daran dich zu informieren. Ich gehe auch durch deinen Blog. Bis jetzt war es fantastisch! – watchtower

+1

Danke, @wachtower. Natürlich ist Sathishs Antwort gut. Ich werde einen Kommentar hinzufügen, der die Verwendung von mean() vorschlägt. Und vielen Dank blogR Feedback! –

Verwandte Themen