write.table เขียนคอลัมน์ว่างชั้นนำที่ไม่ต้องการไปยังส่วนหัวเมื่อมีชื่อแถว


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)

ไชโย Yannick

คำตอบ:


141

การอ้างถึงไฟล์ CSV?write.tableส่วน:

โดยค่าเริ่มต้นจะไม่มีชื่อคอลัมน์สำหรับคอลัมน์ของชื่อแถว ถ้า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 จากสิ่งที่ฉันรู้ว่าคุณทำไม่ได้ คุณสามารถผูกชื่อแถวกับข้อมูลและตั้งชื่อได้ (เหมือนในคำถาม)
Marek

1
@rusalkaguy การแก้ไขของคุณไม่มีประเด็น "ส่วนขยาย" นี้เป็นคำถามเดิม ("วิธีแก้ปัญหาอื่นที่ไม่ใช่")
Marek

คุณจะเอาตัวเลขในแต่ละคอลัมน์มาเรียงกันภายใต้ชื่อ col ได้อย่างไร?
rrs

@rrs คุณหมายถึงรูปแบบความกว้างคงที่? ดูwrite.fwf จากแพคเกจ และถามคำถามใหม่แทนความคิดเห็น และทำไมคุณถึงต้องการสิ่งนั้น!
Marek

10

การแก้ไขเล็กน้อยสำหรับ @Marek คำตอบที่เป็นประโยชน์มากจะเพิ่มส่วนหัวให้กับคอลัมน์ rownames: เพิ่ม rownames เป็นคอลัมน์แรกใน data.frame ชั่วคราวแล้วเขียนโดยไม่สนใจชื่อแถวจริง

> 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

คุณควรแก้ไขคำตอบของ Marek เพื่อรวมสิ่งนี้ด้วยฉันคิดว่า
user8397947

3

สำหรับทุกคนที่ทำงานในtidyverse (dplyr ฯลฯ ) สามารถใช้rownames_to_column()ฟังก์ชันจากtibble package เพื่อแปลง row.names เป็นคอลัมน์ได้อย่างง่ายดายเช่น:

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)และคุณจะเพิ่มอีกครั้ง ฉันลองวิธีแก้ปัญหาข้างต้นแล้วมันไม่ได้ผลดีที่สุดคือย้ายชื่อแถวเป็นคอลัมน์เหมือนในโซลูชันอื่น
aurelien

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' เป็นต้น

ไชโย!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.