2017-05-14 5 views
1

Ich habe in seltsame Problem, wo eine Funktion Aggregat wirkt seltsam, wenn ich es in benutzerdefinierten Funktion aufrufen. Es scheint die Teilmengenfunktion völlig zu übersteuern:Erstellen einer Funktion und Teilmenge von Datenrahmen funktioniert nicht in Aggregatfunktion

Um Ihnen zu geben, was das Problem ist, werde ich es in zwei Teilen brechen. 1. ohne benutzerdefinierte Funktion

c<- data.frame(A = c("carr","bike","truck","carr","truck","bike","bike","carr","truck","carr","truck","truck","carr","truck","truck"), 
       B = c(10,20,30,23,45,56,78,44,10,20,30,10,20,30,67), 
       D = c(1,2,3,1,2,3,2,3,2,3,2,2,3,2,1)) 

c_subset<- subset(c,(A=="carr")|(A=="bike")) 

dg<- aggregate(B ~ D + A ,c_subset,max) 

der Wert dg ist:

D A B   
2 bike 78 
3 bike 56 
1 carr 23 
3 carr 44 

was genau das ist, wie es sein sollte.

Aber 2. Mit benutzerdefinierten Funktion:

rtk <- function(datam,inc_coll,inc_vall,lb,ld){ 
    datam_subset <- subset(c,inc_coll %in% inc_vall) 
    dg1<- aggregate(lb ~ ld + inc_coll,datam_subset,max) 

    return(dg1) 
} 

c_ans <- rtk(c,c$A,c("carr","bike"),c$B,c$D) 

Die Antwort lautet:

ld inc_coll lb 

2 bike 78 
3 bike 56 
1 carr 23 
3 carr 44 
1 truck 67 
2 truck 45 
3 truck 30 

Jetzt möchte ich wissen, warum es "truck" in Aggregatfunktion zu bekommen? Obwohl in Aggregatfunktion habe ich Daten datam_subset verwendet, die eine Teilmenge war und nur Daten auf "Carr" und "Bike" enthält.

Vielleicht fehlt mir etwas sehr einfaches. Seid dankbar für deine Hilfe. Dank

+1

Sie als Eingabe für Ihre Funktion geben 'rtk' die tatsächlichen Spalten Ihrer ursprünglichen datafra ich statt nur Spaltennamen.So funktioniert die "Teilmenge", aber dann wird das "Aggregat" auf den Spalten von "c" ausgeführt. – Lamia

+1

wie niemand es wirklich erwähnt hat. http://stackoverflow.com/questions/9860090/why-is-better-than-subset gibt einige Gedanken über die Verwendung von Teilmenge in einer Funktion. Auch Aggregat hat ein Subset-Argument, das die Dinge leichter machen kann – user20650

+0

* Datam * Param wird nie innerhalb der Funktion verwendet, obwohl Sie 'c'into übergeben – Parfait

Antwort

0

Passing Spaltennamen an eine Funktion ist eine häufig gestellte Frage, wie es nicht eingängig sein kann. Sehen Sie sich diese Frage: Pass a data.frame column name to a function Eine bessere Möglichkeit, Ihre Funktion zu schreiben, wäre passieren die Spaltennamen anstelle der Säulen selbst RTK und dann nutzen sie für das, was Sie tun möchten:

rtk <- function(datam,inc_coll,inc_vall,lb,ld){ 
## Access the column using df[[colname]] to do the subset 
    datam_subset <- subset(c,c[[inc_coll]] %in% inc_vall); 
## Define the formula you will use in the aggregate function 
f=as.formula(paste0(lb,"~",ld,"+", inc_coll)) 
## Perform the aggregation 
    dg1<- aggregate(f,datam_subset,max); 
    return(dg1) 
} 

es dann rufen Sie entsprechend mit Spaltennamen:

c_ans <- rtk(c,"A",c("carr","bike"),"B","D") 

Welche gibt Ihnen:

D A B 
1 2 bike 78 
2 3 bike 56 
3 1 carr 23 
4 3 carr 44 
+0

Danke Lamia für die Erklärung im Detail. @ Yannis Lösung funktioniert auch, aber Ihre ist konfigurierbarer. –

0

Es ist, weil Sie Aggregatfunktion von zwei data.frames Aufruf wird

Dieses:

dg1<- aggregate(lb ~ ld + inc_coll, datam_subset, max) 

tatsächlich liest sich wie:

dg1<- aggregate(c$B ~ c$D + c$A, datam_subset, max) 

so dass Sie die datam_subset Anruf zwingende und Rufen Sie einfach c.

0

Eigentlich gibt es 2 Probleme. Erstens, Sie unterteilen c nicht datam, wie andere hingewiesen haben, aber auch dies löst das Problem nicht. datam_subset hat keine Spalten mit dem Namen lb, ld, inc_call. So sollte Ihre Funktion wie folgt aussehen:

rtk <- function(datam, inc_coll, inc_vall, lb, ld){ 
    datam_subset <- subset(datam, inc_coll %in% inc_vall) 
    names(datam_subset)<- c("inc_coll", "lb", "ld") 
    dg1<- aggregate(lb ~ ld + inc_coll,datam_subset,max) 
    return(dg1) 
} 

> c_ans <- rtk(c,c$A,c("carr","bike"),c$B, c$D) 
> c_ans 
    ld inc_coll lb 
1 2  bike 78 
2 3  bike 56 
3 1  carr 23 
4 3  carr 44 

Sie können die Namen zu c_ans ändern, nur durch colnames(c_ans)<- c("D", "A", "B")

Verwandte Themen