write.table schreibt unerwünschte leere Spalte Kopf führt, wenn rownames hat
-
21-09-2019 - |
Frage
lesen Sie in diesem Beispiel:
> a = matrix(1:9, nrow = 3, ncol = 3, dimnames = list(LETTERS[1:3], LETTERS[1:3]))
> a
A B C
A 1 4 7
B 2 5 8
C 3 6 9
die Tabelle richtig angezeigt wird. Es gibt zwei verschiedene Möglichkeiten, um es Datei zu schreiben ...
write.csv(a, 'a.csv')
, die wie erwartet gibt:
"","A","B","C"
"A",1,4,7
"B",2,5,8
"C",3,6,9
und write.table(a, 'a.txt')
, die Schrauben nach oben
"A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
in der Tat, ein leeres Tab fehlt .... das ist ein Schmerz in den Hintern für Downstream-Dinge ist.
Ist das ein Bug oder ein Feature?
Gibt es eine Abhilfe? (Außer write.table(cbind(rownames(a), a), 'a.txt', row.names=FALSE
)
Cheers, yannick
Lösung
Unter Berufung auf ?write.table
, Abschnitt CSV-Dateien :
Standardmäßig gibt es keine Spaltennamen für eine Spalte von Zeilennamen. Wenn
col.names = NA
undrow.names = TRUE
ein leeres Spaltenname hinzugefügt wird, das ist die Konvention verwendet für CSV-Dateien zu sein Lesen von Tabellen.
So müssen Sie tun
write.table(a, 'a.txt', col.names=NA)
und Sie bekommen
"" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
Andere Tipps
Eine leichte Modifikation zu @Marek sehr hilfreiche Antwort wird einen Header an den rownames Spalte hinzufügen. Vorübergehend die rownames als erste Spalte in der data.frame hinzufügen und schreiben, dass die wirklichen rownames ignorieren
> a = matrix(1:9, nrow = 3, ncol = 3, dimnames = list(LETTERS[1:3], LETTERS[1:3]))
> write.table(data.frame("H"=rownames(a),a),"a.txt", row.names=FALSE)
und Sie bekommen
"H" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
Für alle in der Arbeits tidyverse (dplyr, etc.), die von der Funktion rownames_to_column()
tibble Paket kann auf einfache Weise verwendet werden, konvertieren row.names auf eine Spalte, zum Beispiel:
library('tibble')
a = as.data.frame(matrix(1:9, nrow=3, ncol=3,
dimnames=list(LETTERS[1:3], LETTERS[1:3])))
a %>% rownames_to_column('my_id')
my_id A B C
1 A 1 4 7
2 B 2 5 8
3 C 3 6 9
In Kombination mit der Option row.names=FALSE
in write.table()
Ergebnissen in der Ausgabe mit Header-Namen für alle Spalten.
Für diejenigen, die das gleiche Problem auftreten, wenn eine Matrix mit write.table()
Speichern und wollen die row.names Spalt zu halten, gibt es tatsächlich eine äußerst einfache Lösung:
write.table(matrix,file="file.csv",quote=F,sep=";", row.names=T
col.names=c("row_name_col;val1_col","val2_col"))
Dadurch, dass Sie im Grunde sind tricksen die write.table
Funktion in ein Header-Label für die row.names Säule zu schaffen. Die resultierende CSV-Datei würde wie folgt aussehen:
row_name_col;val1_col;val2_col
row1;1;4
row2;2;5
row3;3;6
I überarbeitet, um eine einfache Funktion von @mnel, die Flexibilität Verbindungen unter Verwendung ergänzt. Hier ist die Funktion:
my.write <- function(x, file, header, f = write.csv, ...){
# create and open the file connection
datafile <- file(file, open = 'wt')
# close on exit
on.exit(close(datafile))
# if a header is defined, write it to the file (@CarlWitthoft's suggestion)
if(!missing(header)) {
writeLines(header,con=datafile, sep='\t')
writeLines('', con=datafile, sep='\n')
}
# write the file using the defined function and required addition arguments
f(x, datafile,...)
}
Sie können die Funktion angeben sein 'write.table', 'write.csv', 'write.delim' etc.
Cheers!