2013-08-22 14 views
7

Ich versuche, Spalten von mehreren data.frame s umzubenennen.Umbenennen Spalten in mehreren Datenrahmen, R

ein Beispiel zu geben, sagen wir, ich dfA, dfB und dfC eine Liste von data.frame s haben. Ich schrieb eine Funktion changeNames Namen entsprechend eingestellt und verwendet dann lapply wie folgt:

dfs <- list(dfA, dfB, dfC) 
ChangeNames <- function(x) { 
    names(x) <- c("A", "B", "C") 
} 
lapply(dfs, ChangeNames) 

Dies ist jedoch nicht wie erwartet. Es sieht so aus, als würde ich die neuen Namen nicht der data.frame zuweisen, sondern nur die neuen Namen erstellen. Was mache ich hier falsch?

Vielen Dank im Voraus!

+0

nach der Zeile 'Namen (x) <-' in Ihrer Funktion, fügen Sie' return (x) 'oder einfach 'X'. Sonst gibst du nur 'names (x)' zurück. – Arun

+0

Vielen Dank für Ihre Antwort Arun! Wenn ich ad (x) zurückgebe, erhalte ich einen Outprint von dfA, dfB und dfC mit den neuen Namen.Aber wenn ich Namen (dfA), Namen (dfB) und Namen (dfC) danach ansehe, haben sie immer noch die alten Spaltennamen. Meine Datenrahmen sind auch sehr groß, so dass ich sie nicht sehen möchte. Nur dort ändern Spaltennamen. – user2706593

+0

'lapply' ändert die Eingabe nicht. Es gibt keine "Änderung durch Referenz", die hier passiert. Alles wird auf einer Kopie gemacht. Sie müssen das Ergebnis zurück zuweisen. do: 'dfs <- lapply (dfs, ChangeNames)' – Arun

Antwort

12

Es gibt zwei Dinge hier:

  • 1) Sie sollten den Wert zurückgeben Sie von Ihrer Funktion möchten. Andernfalls wird der letzte Wert zurückgegeben. In Ihrem Fall ist das names(x). Also, stattdessen sollten Sie als letzte Zeile hinzufügen, return(x) oder einfach x. So würde Ihre Funktion wie folgt aussehen:

    ChangeNames <- function(x) { 
        names(x) <- c("A", "B", "C") 
        return(x) 
    } 
    
  • 2) lapply nicht Ihren Eingangsobjekte ändern Bezug genommen wird. Es funktioniert auf einer Kopie. Also müssen Sie die Ergebnisse zurück zuweisen. Oder eine andere Alternative ist for-loops zu verwenden statt lapply:

    # option 1 
    dfs <- lapply(dfs, ChangeNames) 
    
    # option 2 
    for (i in seq_along(dfs)) { 
        names(dfs[[i]]) <- c("A", "B", "C") 
    } 
    

Auch die for-loop verwenden, werden Sie noch eine Kopie machen (weil names(.) <- . der Fall ist). Sie können dies überprüfen, indem Sie tracemem verwenden.

df <- data.frame(x=1:5, y=6:10, z=11:15) 
tracemem(df) 
# [1] "<0x7f98ec24a480>" 
names(df) <- c("A", "B", "C") 
tracemem(df) 
# [1] "<0x7f98e7f9e318>" 

Wenn Sie mit dem Verweis ändern möchten, können Sie data.table Pakets setnames Funktion:

df <- data.frame(x=1:5, y=6:10, z=11:15) 
require(data.table) 
tracemem(df) 
# [1] "<0x7f98ec76d7b0>" 
setnames(df, c("A", "B", "C")) 
tracemem(df) 
# [1] "<0x7f98ec76d7b0>" 

Sie sehen, dass der Speicherplatz df wird gemappt hat sich nicht geändert. Die Namen wurden durch Bezugnahme geändert.

+0

Dies zu verwenden, um Spaltennamen über mehrere Datenrahmen in einer Liste wie diese zu ändern, war unglaublich hilfreich. Ich verallgemeinerte die Funktion, um ein zweites und drittes Argument zu nehmen, und benutzte das als Eingabe für ein 'grep()', um die Namen bestimmter Spalten in allen meinen Datenrahmen zu ändern. – ano

6

Wenn sich die Datenframes nicht in einer Liste, sondern nur in der globalen Umgebung befinden, können Sie sie mithilfe eines Vektors von String-Namen referenzieren.

Es gibt wahrscheinlich einen Weg, dies zu vereinfachen, ohne auf einen temporären Datensatz zurückgreifen zu müssen, aber ich habe es nicht ausgearbeitet!

-1

Ich hatte das Problem, einen öffentlichen Datensatz zu importieren und jeden Datenrahmen umzubenennen und jede Spalte in jedem Datenrahmen umzubenennen, um Leerzeichen, Kleinbuchstaben zu trimmen und interne Leerzeichen durch Punkte zu ersetzen.

Die Kombination der oben genannten Methoden hat mich:

for (eachdf in dfs) 
    df.tmp <- get(eachdf) 
    for (eachcol in 1:length(df.tmp)) 
     colnames(df.tmp)[eachcol] <- 
     str_trim(str_to_lower(str_replace_all(colnames(df.tmp)[eachcol], " ", "."))) 
     } 
    assign(eachdf, df.tmp) 
} 
Verwandte Themen