2012-11-15 17 views
19

Ich habe eine Liste von Dateien. Ich habe auch eine Liste von "Namen", die ich substr() aus den tatsächlichen Dateinamen dieser Dateien. Ich möchte zu jeder der Dateien in der Liste eine neue Spalte hinzufügen. Diese Spalte enthält das entsprechende Element in "Namen", das die Anzahl der Zeilen in der Datei wiederholt.Hinzufügen einer neuen Spalte zu jedem Element in einer Liste von Tabellen oder Datenrahmen

Zum Beispiel:

df1 <- data.frame(x = 1:3, y=letters[1:3]) 
df2 <- data.frame(x = 4:6, y=letters[4:6]) 
filelist <- list(df1,df2) 
ID <- c("1A","IB") 

Pseudocode

for(i in length(filelist)){ 

     filelist[i]$SampleID <- rep(ID[i],nrow(filelist[i]) 

    } 

// grundsätzlich eine neue Spalte in jedem der Datenrahmen in Liste der Dateien, erstellen und die Spalte mit repeted entsprechenden Werte von ID füllen

mein Ausgang sollte wie sein:

filelist[1] sollte sein:

x y SAmpleID 
1 1 a  1A 
2 2 b  1A 
3 3 c  1A 

fileList[2]

x y SampleID 
1 4 d  IB 
2 5 e  IB 
3 6 f  IB 

und so weiter .....

Jede Idee, wie es getan werden könnte.

Antwort

24

Eine alternative Lösung ist cbind zu verwenden, und den Vorteil der Tatsache, dass R werden Werte einer kürzeren recylce Vektor.

Für Beispiel

x <- df2 # from above 
cbind(x, NewColumn="Singleton") 
# x y NewColumn 
# 1 4 d Singleton 
# 2 5 e Singleton 
# 3 6 f Singleton 

Es besteht keine Notwendigkeit für den Einsatz von rep. R macht das für dich.

Therfore, könnten Sie cbind(filelist[[i]], ID[[i]]) in Ihrem for loop setzen oder als @Sven darauf hingewiesen, können Sie den Reiniger mapply verwenden:

filelist <- mapply(cbind, filelist, "SampleID"=ID, SIMPLIFY=F) 
+4

Vielen Dank für Ihre Hilfe und außergewöhnliche Ansätze. Die for-Schleife, die Mapply() und die Cbind funktionieren wie ein Zauber. Es ist faszinierend, eine Sprache wie diese zu lernen und ich lerne jedes Mal etwas Neues, wenn ich eine Frage auf diesem Brett stelle. Es tut mir leid, dass ich nicht früher schreiben konnte, um meine Dankbarkeit und Wertschätzung auszudrücken. Vielen Dank – user1079898

16

Dies ist eine korrigierte Version der Schleife:

for(i in seq_along(filelist)){ 

    filelist[[i]]$SampleID <- rep(ID[i],nrow(filelist[[i]])) 

} 

Es gab 3 Probleme:

  • Ein abschließendes ) wurde im Körper nach dem Befehl fehlen.
  • Elemente der Listen werden von [[, nicht von [ zugegriffen. gibt eine Liste der Länge eins zurück. [[ gibt nur das Element zurück.
  • length(filelist) ist nur ein Wert, so dass die Schleife nur für das letzte Element der Liste ausgeführt wird. Ich habe es durch seq_along(filelist) ersetzt.

Ein effizienterer Ansatz ist mapply für die Aufgabe zu verwenden:

mapply(function(x, y) "[<-"(x, "SampleID", value = y) , 
     filelist, ID, SIMPLIFY = FALSE) 
+12

Sie wirklich anonym nicht brauchen Funktion in 'Mapply'. '' Mapply ('[<-', Dateiliste, 'ProbeID', Wert = ID, SIMPLIFY = FALSE) '' – mnel

+0

@mnel +1 Große Idee funktioniert, danke. –

+0

Ich habe deine Antwort auch angenommen. Ich dachte, du könntest zwei Antworten akzeptieren, da sie alle sehr hilfreich waren. Es tut mir leid, aber ich wollte dich nicht beleidigen. Eigentlich war die For-Schleife großartig und die Erklärung sehr hilfreich. Ich danke dir sehr! – user1079898

1

Eine schwierige Art und Weise:

library(plyr) 

names(filelist) <- ID 
result <- ldply(filelist, data.frame) 
Verwandte Themen