write.table scrive indesiderato conduce colonna vuota di intestazione quando ha rownames

StackOverflow https://stackoverflow.com/questions/2478352

  •  21-09-2019
  •  | 
  •  

Domanda

controllare questo esempio:

> 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

la tabella visualizza correttamente. Ci sono due modi diversi di scrivere in un file ...

write.csv(a, 'a.csv') che dà come previsto:

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

e write.table(a, 'a.txt') che si avvita fino

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

In effetti, una scheda vuota manca .... che è un dolore nel culo per le cose a valle. Si tratta di un bug o una funzione? C'è una soluzione? (Diverso write.table(cbind(rownames(a), a), 'a.txt', row.names=FALSE)

Saluti, yannick

È stato utile?

Soluzione

Citando ?write.table, sezione file CSV :

  

Per impostazione predefinita non v'è alcun nome di colonna per   una colonna di nomi di riga. Se col.names = NA e row.names = TRUE un vuoto   viene aggiunto il nome della colonna, che è il   convenzione usata per CSV file da   letto da fogli di calcolo.

Quindi è necessario fare

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

e si ottiene

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

Altri suggerimenti

Una leggera modifica al @Marek risposta molto utile aggiungerà un colpo di testa alla colonna rownames:. Aggiungere temporaneamente le rownames come la prima colonna nella data.frame, e scrivere che, ignorando i veri 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)

e si ottiene

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

Per tutti coloro che lavorano nel tidyverse (dplyr, ecc), la funzione rownames_to_column() dalla pacchetto Tibble può essere utilizzato per convertire facilmente row.names ad una colonna, ad esempio:

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

Combinando questo con l'opzione row.names=FALSE nei risultati write.table() in uscita con i nomi di intestazione per tutte le colonne.

Per coloro che sperimentano lo stesso problema durante il salvataggio di una matrice con write.table() e vogliono mantenere la colonna row.names, non v'è in realtà una soluzione estremamente semplice:

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

In questo che si sta praticamente ingannando la funzione write.table nella creazione di un'etichetta di intestazione per la colonna row.names. Il file .csv risultante sarebbe simile a questa:

row_name_col;val1_col;val2_col
row1;1;4 
row2;2;5 
row3;3;6 

ho rivisto una funzione semplice da @mnel, che aggiunge flessibilità utilizzando connessioni. Ecco la funzione:

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

È possibile specificare la funzione di essere, 'write.csv' 'write.table', 'write.delim' etc.

Cheers!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top