write.table writes unwanted leading empty column to header when has rownames
check this example:
> 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
the table displays correctly. There are two different ways of writing it to file...
write.csv(a, 'a.csv')
which gives as expected:
"","A","B","C"
"A",1,4,7
"B",2,5,8
"C",3,6,9
and write.table(a, 'a.txt')
which screws up
"A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
indeed, an empty tab is missing.... which is a pain in the butt for downstream things.
Is this a bug or a feature?
Is there a workaround? (other than write.table(cbind(rownames(a), a), 'a.txt', row.names=FALSE
)
Cheers, yannick
Solution 1:
Citing ?write.table
, section CSV files:
By default there is no column name for a column of row names. If
col.names = NA
androw.names = TRUE
a blank column name is added, which is the convention used for CSV files to be read by spreadsheets.
So you must do
write.table(a, 'a.txt', col.names=NA)
and you get
"" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
Solution 2:
A slight modification to @Marek very helpful answer WILL add a header to the rownames column: temporarily add the rownames as the first column in the data.frame, and write that, ignoring the real rownames.
> 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)
and you get
"H" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9