2013-02-12 3 views
5

Ich habe eine kleine Frage über Funktionen anwenden. Zum Beispiel habe ich:Wie teilt man eine Liste von data.frame auf und wendet eine Funktion auf eine Spalte an?

l <- list(a = data.frame(A1=rep(10,5),B1=c(1,1,1,2,2),C1=c(5,10,20,7,30)), 
      b = data.frame(A1=rep(20,5),B1=c(3,3,4,4,4),C1=c(3,5,10,20,30))) 

Ich möchte ein Minimum C1 für jeden B1 zu finden. Das Ergebnis sollte

sein
$a 
    A1 B1 C1 
    10 1 5 
    10 2 7 

$b 
    A1 B1 C1 
    20 3 3 
    20 4 10 

Ich weiß, wie es zu tun mit ‚für‘, aber es muss ein einfacher Weg, um mit ‚lapply‘, aber ich konnte nicht machen es funktioniert.

Bitte helfen

Antwort

2

Hier ist ein weiterer Ansatz, die Ihren gewünschten Ausgang entspricht:

lapply(l, function(x) { 
    temp <- ave(x[["C1"]], x["B1"], FUN = min) 
    x[x[["C1"]] == temp, ] 
}) 
# $a 
# A1 B1 C1 
# 1 10 1 5 
# 4 10 2 7 
# 
# $b 
# A1 B1 C1 
# 1 20 3 3 
# 3 20 4 10 
+0

das ist genau das, was ich wollte, vielen Dank. Ich kannte diese Art von Ave-Nutzung nicht – Tali

3

Was lapply und tapply Kombination:

lapply(l, function(i) tapply(i$C1, i$B1, min)) 
$a 
1 2 
5 7 

$b 
3 4 
3 10 

Der Trick über mehrere Operationen zu denken, ist die Aufgabe in Bits aufgeteilt. SO,

  1. Mindest C1 für jede B1. Wie machen wir das für einen einzigen Datenrahmen?

    i = l[[1]] 
    tapply(i$C1, i$B1, min) 
    
  2. Jedes Element einer Liste? Nur lapply verwenden:

    lapply(l, function(i) tapply(i$C1, i$B1, min)) 
    

Wenn Sie nicht Schritt 1 tun können, werden Sie nicht in der Lage sein, Schritt zu verwalten 2.

+0

Vielen Dank – Tali

0

Sie können auch versuchen llply + dcast vom plyr/reshape2 Toolbox:

library(reshape2) 
library(plyr) 

    l <- list(a = data.frame(A1=rep(10,5),B1=c(1,1,1,2,2),C1=c(5,10,20,7,30)), 
       b = data.frame(A1=rep(20,5),B1=c(3,3,4,4,4),C1=c(3,5,10,20,30))) 

    llply(l, function (x) {dcast (x, A1+B1~., value.var="C1", min)}) 
3

Nachdem erliegen kürzlich den Sirenengesang des data.table Pakets und seine Kombination aus Vielseitigkeit und Geschwindigkeit für Operationen wie dies zu tun, ich einreichen noch eine andere Lösung:

library(data.table) 
lapply(l, function(dat) { 
    data.table(dat, key="B1,C1")[list(unique(B1)), mult="first"] 
}) 

Wenn die ursprüngliche Spaltenreihenfolge beibehalten wichtig ist, für aus irgendeinem Grund könnte der data.table() Aufruf von setcolorder(..., names(dat)) umbrochen werden.