write.table menulis kolom kosong di depan yang tidak diinginkan ke header ketika memiliki nama baris

91

periksa contoh ini:

> 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

tabel ditampilkan dengan benar. Ada dua cara berbeda untuk menulisnya ke file ...

write.csv(a, 'a.csv') yang memberikan seperti yang diharapkan:

"","A","B","C"
"A",1,4,7
"B",2,5,8
"C",3,6,9

dan write.table(a, 'a.txt')yang mengacaukan

"A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9

memang, tab kosong tidak ada .... yang merepotkan untuk hal-hal hilir. Apakah ini bug atau fitur? Apakah ada solusinya? (selain write.table(cbind(rownames(a), a), 'a.txt', row.names=FALSE)

Cheers, yannick

Yannick Wurm
sumber

Jawaban:

140

Mengutip ?write.table, file CSV bagian :

Secara default, tidak ada nama kolom untuk kolom dengan nama baris. Jika col.names = NAdan row.names = TRUEnama kolom kosong ditambahkan, yang merupakan konvensi yang digunakan untuk file CSV untuk dibaca oleh spreadsheet.

Jadi, Anda harus melakukannya

write.table(a, 'a.txt', col.names=NA)

dan kamu mendapatkan

"" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
Marek
sumber
4
@ Marek, apakah mungkin menambahkan nama ke kolom rownames? Yaitu, alih-alih "", tambahkan "ID" atau sesuatu yang serupa?
Dnaiel
2
@Dnaiel Dari apa yang saya tahu Anda tidak bisa. Anda dapat mengikat nama baris dengan data dan memberinya nama (seperti dalam pertanyaan).
Marek
1
@rusalkaguy Hasil edit Anda tidak ada gunanya. Ini "ekstensi" dalam pertanyaan asli ("solusi selain")
Marek
Bagaimana Anda membuat nomor di setiap kolom berbaris di bawah nama kolom?
rrs
@rrs Maksud Anda format lebar tetap? Lihat write.fwf dari paket gdata . Dan ajukan pertanyaan baru, bukan komentar. Dan mengapa Anda membutuhkan itu ?!
Marek
10

Sedikit modifikasi pada @Marek, jawaban yang sangat membantu AKAN menambahkan tajuk ke kolom rownames: tambahkan sementara nama rowname sebagai kolom pertama di data.frame, dan tulislah, mengabaikan nama rown yang sebenarnya.

> 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)

dan kamu mendapatkan

"H" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
rusalkaguy
sumber
Anda harus mengedit jawaban Marek untuk memasukkan ini, saya kira.
pengguna8397947
3

Bagi siapa pun yang bekerja di tidyverse (dplyr, dll.), rownames_to_column()Fungsi dari paket tibble dapat digunakan untuk dengan mudah mengubah nama baris menjadi kolom, misalnya:

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

Menggabungkan ini dengan row.names=FALSEopsi dalam write.table()menghasilkan keluaran dengan nama tajuk untuk semua kolom.

Keith Hughitt
sumber
1

Bagi mereka yang mengalami masalah yang sama saat menyimpan matriks dengan write.table()dan ingin mempertahankan kolom row.names, sebenarnya ada solusi yang sangat sederhana:

 write.table(matrix,file="file.csv",quote=F,sep=";", row.names=T
             col.names=c("row_name_col;val1_col","val2_col"))

Dengan melakukan itu Anda pada dasarnya menipu write.tablefungsi untuk membuat label header untuk kolom row.names. File .csv yang dihasilkan akan terlihat seperti ini:

row_name_col;val1_col;val2_col
row1;1;4 
row2;2;5 
row3;3;6 
uribalb.dll
sumber
Saya mencoba col.names = c ("row_name", colnames (matrix)) dan mendapatkan kesalahan yang mengatakan spesifikasi 'col.names' tidak valid. Apakah ada yang salah? c ("row_name", colnames (matrix)) memberikan teks yang benar.
MichaelE
write.tablemengharapkan sebuah header dengan panjang ncol(matrix)dan Anda memberikannya satu lagi. Saya mencoba solusi di atas, tidak berhasil, yang terbaik adalah memindahkan nama baris sebagai kolom seperti dalam solusi lain
aurelien
0

Saya merevisi fungsi sederhana dari @mnel, yang menambahkan fleksibilitas dengan menggunakan koneksi. Berikut fungsinya:

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,...)
}

Anda dapat menentukan fungsinya menjadi 'write.table', 'write.csv', 'write.delim' dll.

Bersulang!

yuanhangliu1
sumber