Write.Table escreve coluna de liderança indesejada para o cabeçalho, quando houver rowneames
-
21-09-2019 - |
Pergunta
Verifique este exemplo:
> 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
A tabela é exibida corretamente. Existem duas maneiras diferentes de escrevê -lo para arquivar ...
write.csv(a, 'a.csv')
O que dá conforme o esperado:
"","A","B","C"
"A",1,4,7
"B",2,5,8
"C",3,6,9
e write.table(a, 'a.txt')
que estraga tudo
"A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
De fato, falta uma guia vazia ... o que é uma dor na bunda para coisas a jusante. isso é um erro ou uma característica? Existe uma solução alternativa? (outro que não seja write.table(cbind(rownames(a), a), 'a.txt', row.names=FALSE
)
Saúde, Yannick
Solução
Citando ?write.table
, seção Arquivos CSV:
Por padrão, não há nome de coluna para uma coluna de nomes de linha. Se
col.names = NA
erow.names = TRUE
Um nome de coluna em branco é adicionado, que é a convenção usada para os arquivos CSV a serem lidos por planilhas.
Então você deve fazer
write.table(a, 'a.txt', col.names=NA)
e você entendeu
"" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
Outras dicas
Uma ligeira modificação para @marek muito útil adicionará um cabeçalho à coluna da RowNames: adicione temporariamente os Rowns Nomes como a primeira coluna no Data.frame e escreva isso, ignorando os verdadeiros nomes.
> 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 você entendeu
"H" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
Para quem trabalha no Tidyverse (dplyr, etc.), o rownames_to_column()
função do Tibble O pacote pode ser usado para converter facilmente a linha.names em uma coluna, por exemplo:
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 isso com o row.names=FALSE
opção em write.table()
Resultados na saída com nomes de cabeçalho para todas as colunas.
Para aqueles que experimentam o mesmo problema ao salvar uma matriz com write.table()
E quero manter a coluna ROW.NAMES, na verdade, há uma solução extremamente simples:
write.table(matrix,file="file.csv",quote=F,sep=";", row.names=T
col.names=c("row_name_col;val1_col","val2_col"))
Ao fazer isso, você está basicamente enganando o write.table
Função na criação de um rótulo de cabeçalho para a coluna ROW.Names. O arquivo .csv resultante ficaria assim:
row_name_col;val1_col;val2_col
row1;1;4
row2;2;5
row3;3;6
Revisei uma função simples do @mnel, que adiciona flexibilidade usando conexões. Aqui está a função:
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,...)
}
Você pode especificar a função a ser 'write.table', 'write.csv', 'write.delim' etc.
Felicidades!