2015-12-01 17 views
5

Ich habe eine .RData-Datei auf meinem Linux (UTF-8) -Maschine zu lesen, aber ich weiß, dass die Datei in Latin1 ist, weil ich sie selbst auf Windows erstellt habe. Leider habe ich keinen Zugriff auf die Originaldateien oder einen Windows-Rechner und muss diese Dateien auf meinem Linux-Rechner lesen.Rdata-Datei mit unterschiedlicher Codierung lesen

Um eine Rdata-Datei zu lesen, wird normalerweise load("file.Rdata") ausgeführt. Funktionen wie read.csv haben ein encoding Argument, das Sie verwenden können, um diese Art von Problemen zu lösen, aber load hat keine solche Sache. Wenn ich load("file.Rdata", encoding = latin1) versuchen, bekomme ich nur diese (erwartet) Fehler:

Error in load("file.Rdata", encoding = "latin1") : unused argument (encoding = "latin1")

Was kann ich sonst noch tun? Meine Dateien werden mit Textvariablen geladen, die Akzente enthalten, die beim Öffnen in einer UTF-8-Umgebung beschädigt werden.

+2

RData-Dateien haben keine Codierungen. Sie müssen die serialisierten Rdata laden und die Werte erneut codieren, sobald sie sich im R-Arbeitsbereich befinden. Bleibt dies nach dem Lesen von "? Encoding" unklar, laden Sie die Ausgabe von "dput (head (object))" und stellen Sie sie dort ab. –

+0

@ 42, scheint dies das Problem zu lösen, schade, anscheinend muss ich 'Encoding (x)' auf jeden Vektor in meinem Datenrahmen anwenden. Ich werde es mir genauer ansehen und werde zu dir zurückkommen. –

+0

Sie können die Namen im Arbeitsbereich vor und nach dem Laden aufzeichnen und dann die Unterschiede für die Elemente mit Zeichenwerten bearbeiten. –

Antwort

3

Dank 42 Kommentar, ich habe eine Funktion neu zu kodieren, die Datei schreiben verwaltet:

fix.encoding <- function(df, originalEncoding = "latin1") { 
    numCols <- ncol(df) 
    for (col in 1:numCols) Encoding(df[, col]) <- originalEncoding 
    return(df) 
} 

Das Fleisch hier ist der Befehl Encoding(df[, col]) <- "latin1", die Spalte col von Datenrahmen df und wandelt sie nimmt Format latin1 . Leider nimmt Encoding nur Spaltenobjekte als Eingabe, also musste ich eine Funktion erstellen, um alle Spalten eines Datenrahmenobjekts zu durchsuchen und die Transformation anzuwenden.

Natürlich, wenn Ihr Problem in nur ein paar Spalten ist, ist es besser, nur die Encoding auf diese Spalten anstelle des gesamten Datenrahmens anwenden (Sie können die Funktion oben ändern, um eine Reihe von Spalten als Eingabe zu nehmen). Wenn Sie mit dem umgekehrten Problem konfrontiert sind, d. H. Ein R-Objekt lesen, das unter Linux oder Mac OS in Windows erstellt wurde, sollten Sie originalEncoding = "UTF-8" verwenden.

1

Vielen Dank für das Posten. Ich habe mir die Freiheit genommen, Ihre Funktion zu modifizieren, falls Sie einen Datenrahmen mit einigen Spalten als Zeichen und manche als Nicht-Zeichen haben. Andernfalls tritt ein Fehler auf:

> fix.encoding(adress) 
Error in `Encoding<-`(`*tmp*`, value = "latin1") : 
a character vector argument expected 

So, hier ist die modifizierte Funktion:

fix.encoding <- function(df, originalEncoding = "latin1") { 
    numCols <- ncol(df) 
    for (col in 1:numCols) 
      if(class(df[, col]) == "character"){ 
        Encoding(df[, col]) <- originalEncoding 
      } 
    return(df) 
} 

Dies wird jedoch nicht die Kodierung von Namen der Ebene ändern, in einer „Faktor“ Spalte. Glücklicherweise fand ich dies alle Faktoren in Ihrem Datenrahmen zu Zeichen ändern (was nicht der beste Ansatz sein kann, aber in meinem Fall, das ist das, was ich brauchte):

i <- sapply(df, is.factor) 
df[i] <- lapply(df[i], as.character) 
1

auf frühere Antworten folgende, ist dies ein kleines update, das es auf Faktoren und dplyr's tibble arbeiten lässt. Danke für die Inspiration.

fix.encoding <- function(df, originalEncoding = "UTF-8") { 
numCols <- ncol(df) 
df <- data.frame(df) 
for (col in 1:numCols) 
{ 
     if(class(df[, col]) == "character"){ 
       Encoding(df[, col]) <- originalEncoding 
     } 

     if(class(df[, col]) == "factor"){ 
         Encoding(levels(df[, col])) <- originalEncoding 
} 
} 
return(as_data_frame(df)) 
}