write.table записывает нежелательный ведущий пустой столбец в заголовок, когда имеет rownames

92

проверьте этот пример:

> 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

таблица отображается правильно. Есть два разных способа записать его в файл ...

write.csv(a, 'a.csv') что дает, как и ожидалось:

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

и write.table(a, 'a.txt')который лажает

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

действительно, пустая вкладка отсутствует .... что является головной болью для последующих вещей. Это ошибка или особенность? Есть ли обходной путь? (кроме write.table(cbind(rownames(a), a), 'a.txt', row.names=FALSE)

Привет, Янник

Янник Вурм
источник

Ответы:

141

Цитирование ?write.table, раздел CSV-файлы :

По умолчанию для столбца с именами строк нет имени столбца. Если col.names = NAи row.names = TRUEдобавлено пустое имя столбца, это соглашение, используемое для чтения файлов CSV в электронных таблицах.

Так что ты должен сделать

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

и вы получите

"" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
Марек
источник
4
@Marek, можно ли добавить имя в столбец rownames? Т.е. вместо "" добавить "ID" или что-то подобное?
Dnaiel
2
@Dnaiel Насколько я знаю, ты не сможешь. Вы можете связать имена строк с данными и дать им имена (как в вопросе).
Марек
1
@rusalkaguy В твоем редактировании нет смысла. Это «расширение» находится в исходном вопросе («обходное решение, кроме»)
Марек
Как бы вы добились того, чтобы число в каждом столбце соответствовало названиям столбцов?
РРП
@rrs Вы про формат фиксированной ширины? Посмотрите write.fwf из пакета gdata . И задайте новый вопрос вместо комментария. И зачем тебе это вообще нужно ?!
Марек
10

Небольшая модификация очень полезного ответа @Marek добавит заголовок в столбец rownames: временно добавьте rownames в качестве первого столбца в data.frame и напишите это, игнорируя настоящие 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)

и вы получите

"H" "A" "B" "C"
"A" 1 4 7
"B" 2 5 8
"C" 3 6 9
Русалкагуй
источник
Я думаю, вам следует отредактировать ответ Марека, чтобы включить это.
user8397947 07
3

Для всех, кто работает в tidyverse (dplyr и т. Д.), rownames_to_column()Функцию из пакета tibble можно использовать для простого преобразования имен row.name в столбец, например:

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

Объединение этого с row.names=FALSEопцией в write.table()приводит к выводу с именами заголовков для всех столбцов.

Кейт Хьюитт
источник
1

Для тех, кто сталкивается с той же проблемой при сохранении матрицы write.table()и хочет сохранить столбец row.names, на самом деле есть чрезвычайно простое решение:

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

Делая это, вы в основном обманываете write.tableфункцию, создавая метку заголовка для столбца row.names. Полученный файл .csv будет выглядеть так:

row_name_col;val1_col;val2_col
row1;1;4 
row2;2;5 
row3;3;6 
Урибалб
источник
Я пытаюсь выполнить col.names = c ("row_name", colnames (matrix)) и получаю сообщение об ошибке, указывающее на недопустимую спецификацию 'col.names'. Есть идеи, что не так? c ("row_name", colnames (matrix)) дает правильный текст.
MichaelE
write.tableожидайте заголовок длины, ncol(matrix)и вы даете ему еще один. Я попробовал вышеуказанное решение, оно не работает. Лучше всего переместить названия строк в виде столбца, как в других решениях
Орелиен,
0

Я переработал простую функцию из @mnel, которая добавляет гибкости за счет использования соединений. Вот функция:

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

Вы можете указать функцию write.table, write.csv, write.delim и т. Д.

Ура!

yuanhangliu1
источник