Frage

Ich habe einen Daten.Frame mit dem Namen "D" von ~ 1.300.000 Zeilen und 4 Spalten und einem weiteren Daten.Frame mit dem Namen "GC" von ~ 12.000 Zeilen und 2 Spalten (siehe jedoch das kleinere Beispiel unten).

d <- data.frame( gene=rep(c("a","b","c"),4), val=rnorm(12), ind=c( rep(rep("i1",3),2), rep(rep("i2",3),2) ), exp=c( rep("e1",3), rep("e2",3), rep("e1",3), rep("e2",3) ) )
gc <- data.frame( gene=c("a","b","c"), chr=c("c1","c2","c3") )

So sieht "D" aus:

   gene         val ind exp
1     a  1.38711902  i1  e1
2     b -0.25578496  i1  e1
3     c  0.49331256  i1  e1
4     a -1.38015272  i1  e2
5     b  1.46779219  i1  e2
6     c -0.84946320  i1  e2
7     a  0.01188061  i2  e1
8     b -0.13225808  i2  e1
9     c  0.16508404  i2  e1
10    a  0.70949804  i2  e2
11    b -0.64950167  i2  e2
12    c  0.12472479  i2  e2

Und hier ist "GC":

  gene chr
1    a  c1
2    b  c2
3    c  c3

Ich möchte "D" eine 5. Spalte hinzufügen, indem ich Daten von "GC" einbeziehe, die mit der 1. Spalte von "D" übereinstimmen. Für den Moment benutze ich schlau.

d$chr <- sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )

Bei den realen Daten dauert es jedoch eine "sehr lange" Zeit (ich führe den Befehl mit "System.Time ()" seit mehr als 30 Minuten aus und ist immer noch nicht fertig).

Haben Sie eine Vorstellung davon, wie ich das auf clevere Weise umschreiben könnte? Oder sollte ich in Betracht ziehen, zu verwenden PLYR, Vielleicht mit der "parallelen" Option (ich habe vier Kerne auf meinem Computer)? Was wäre in einem solchen Fall die beste Syntax?

Danke im Voraus.

War es hilfreich?

Lösung

Ich denke, Sie können den Faktor nur als Index verwenden:

gc[ d[,1], 2]
 [1] c1 c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3
Levels: c1 c2 c3

macht das gleiche wie:

 sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )
 [1] c1 c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3
Levels: c1 c2 c3

Aber ist viel schneller:

> system.time(replicate(1000,sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )))
   user  system elapsed 
   5.03    0.00    5.02 
> 
> system.time(replicate(1000,gc[ d[,1], 2]))
   user  system elapsed 
   0.12    0.00    0.13 

Bearbeiten:

Ein bisschen in meinem Kommentar zu erweitern. Das gc DataFrame erfordert eine Zeile für jede Ebene von gene in der Reihenfolge der Ebenen, damit dies funktioniert:

 d <- data.frame( gene=rep(c("a","b","c"),4), val=rnorm(12), ind=c( rep(rep("i1",3),2), rep(rep("i2",3),2) ), exp=c( rep("e1",3), rep("e2",3), rep("e1",3), rep("e2",3) ) )
gc <- data.frame( gene=c("c","a","b"), chr=c("c1","c2","c3") )

gc[ d[,1], 2]
 [1] c1 c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3
Levels: c1 c2 c3

sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )
 [1] c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3 c1
Levels: c1 c2 c3

Aber es ist nicht schwer zu beheben:

levels(gc$gene) <- levels(d$gene) # Seems redundant as this is done right quite often automatically
gc <- gc[order(gc$gene),]


gc[ d[,1], 2]
 [1] c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3 c1
Levels: c1 c2 c3

sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )
 [1] c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3 c1
Levels: c1 c2 c3

Andere Tipps

Eine alternative Lösung, die Sashas Ansatz nicht übertroffen, aber verallgemeinerbarer und lesbarer ist, ist einfach einfach merge Die beiden Datenrahmen:

d <- merge(d, gc)

Ich habe ein langsameres System, also hier sind mein Zeitpunkt:

> system.time(replicate(1000,sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )))
   user  system elapsed 
  11.22    0.12   11.86 
> system.time(replicate(1000,gc[ d[,1], 2])) 
   user  system elapsed 
   0.34    0.00    0.35 
> system.time(replicate(1000, merge(d, gc, by="gene"))) 
   user  system elapsed 
   3.35    0.02    3.40 

Der Vorteil ist, dass Sie mehrere Schlüssel, eine feine Kontrolle über nicht übereinstimmende Gegenstände haben können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top