【问题标题】:write.table writes unwanted leading empty column to header when has rownames当有行名时,write.table 将不需要的前导空列写入标题
【发布时间】:2011-01-29 12:26:43
【问题描述】:

检查这个例子:

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

干杯, 亚尼克

【问题讨论】:

    标签: r export-to-csv write.table


    【解决方案1】:

    引用?write.tableCSV 文件部分:

    默认情况下没有列名 一列行名。如果col.names = NArow.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
    

    【讨论】:

    • @Marek,是否可以在 rownames 列中添加名称?即,代替“”,添加“ID”或类似的东西?
    • @Dnaiel 据我所知你不能。您可以将行名称与数据绑定并给它们命名(就像问题一样)。
    • @rusalkaguy 您的编辑毫无意义。这个“扩展”是原始问题(“解决方法”)
    • 如何让每列中的数字在列名下对齐?
    • @rrs 你的意思是固定宽度格式?看write.fwf from gdata package。并提出新问题而不是评论。为什么你需要它?!
    【解决方案2】:

    对@Marek 非常有用的答案稍作修改将在行名列中添加一个标题:临时将行名添加为 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 的答案以包含此内容。
    【解决方案3】:

    对于在tidyverse(dplyr 等)中工作的任何人,tibble 包中的rownames_to_column() 函数可用于轻松地将 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
    

    将其与write.table() 中的row.names=FALSE 选项结合使用会生成带有所有列标题名称的输出。

    【讨论】:

      【解决方案4】:

      对于那些在使用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)) 给出正确的文本。
      • write.table 期望一个长度为 ncol(matrix) 的标题,而您又给了它一个。我尝试了上面的解决方案,它不起作用,最好是像其他解决方案一样将行名移动为列
      【解决方案5】:

      我从@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'等

      干杯!

      【讨论】:

        猜你喜欢
        • 2012-06-14
        • 2013-06-19
        • 1970-01-01
        • 2017-01-16
        • 2014-11-27
        • 2010-12-19
        • 2016-01-19
        • 1970-01-01
        • 2021-06-24
        相关资源
        最近更新 更多