【问题标题】:Markdown table to data frame in R降价表到R中的数据框
【发布时间】:2018-06-13 17:46:34
【问题描述】:

有多种方法可以将数据框转换为 Markdown 表。 但是,如何在给定 Markdown 表的情况下转换回数据框

给定一个表格:

Table Header | Second Header
------------- | -------------
Table Cell | Cell 2
Cell 3 | Cell 4 

或者,更糟糕的是,以一种形式

Table Header | Second Header \n------------- | ------------- \nTable Cell | Cell 2 \nCell 3 | Cell 4 

如何将其放入数据框中?

【问题讨论】:

    标签: r markdown r-markdown readr


    【解决方案1】:

    我编写了几个函数来处理这些问题,尽管我怀疑对于编写 SO 答案的人来说,这比其他任何人都更容易出现问题。无论如何:

    # base R version
    read.markdown <- function(file, stringsAsFactors = FALSE, strip.white = TRUE, ...){
        if (length(file) > 1) {
            lines <- file
        } else if (grepl('\n', file)) {
            con <- textConnection(file)
            lines <- readLines(con)
            close(con)
        } else {
            lines <- readLines(file)
        }
        lines <- lines[!grepl('^[[:blank:]+-=:_|]*$', lines)]
        lines <- gsub('(^\\s*?\\|)|(\\|\\s*?$)', '', lines)
        read.delim(text = paste(lines, collapse = '\n'), sep = '|', 
                   stringsAsFactors = stringsAsFactors, strip.white = strip.white, ...)
    }
    
    # readr version
    read_markdown <- function(file, trim_ws = TRUE, ...){
        if (length(file) > 1) {
            lines <- file
        } else {
            lines <- readr::read_lines(file)
        }
        lines <- lines[!grepl('^[[:blank:]+-=:_|]*$', lines)]
        lines <- gsub('(^\\s*?\\|)|(\\|\\s*?$)', '', lines)
        readr::read_delim(paste(lines, collapse = '\n'), delim = '|', 
                          trim_ws = trim_ws, ...)
    }
    

    他们可以处理多种降价表,并且对单个字符串感到满意:

    read.markdown('Table Header | Second Header \n------------- | ------------- \nTable Cell | Cell 2 \nCell 3 | Cell 4 ')
    #>   Table.Header Second.Header
    #> 1   Table Cell        Cell 2
    #> 2       Cell 3        Cell 4
    

    线向量(就像从clipr::read_clip 得到的一样):

    clipr::write_clip(
    ' |                     |  mpg  |  cyl  |  disp  |  hp  |
     |:-------------------:|:-----:|:-----:|:------:|:----:|
     |      Mazda RX4      |  21   |   6   |  160   | 110  |
     |    Mazda RX4 Wag    |  21   |   6   |  160   | 110  |
     |     Datsun 710      | 22.8  |   4   |  108   |  93  |'
    )
    
    read.markdown(clipr::read_clip())
    #>               X  mpg cyl disp  hp
    #> 1     Mazda RX4 21.0   6  160 110
    #> 2 Mazda RX4 Wag 21.0   6  160 110
    #> 3    Datsun 710 22.8   4  108  93
    

    或文件名(虽然文件只能包含表格和空格):

    tmp <- tempfile()
    writeLines(
    ' +---------------------+-------+-------+--------+------+--------+
     |                     |  mpg  |  cyl  |  disp  |  hp  |  drat  |
     +=====================+=======+=======+========+======+========+
     |      Mazda RX4      |  21   |   6   |  160   | 110  |  3.9   |
     +---------------------+-------+-------+--------+------+--------+
     |    Mazda RX4 Wag    |  21   |   6   |  160   | 110  |  3.9   |
     +---------------------+-------+-------+--------+------+--------+
     |     Datsun 710      | 22.8  |   4   |  108   |  93  |  3.85  |
     +---------------------+-------+-------+--------+------+--------+',
    tmp
    )
    
    read_markdown(tmp)
    #> Warning: Missing column names filled in: 'X1' [1]
    #> # A tibble: 3 x 6
    #>   X1              mpg   cyl  disp    hp  drat
    #>   <chr>         <dbl> <int> <int> <int> <dbl>
    #> 1 Mazda RX4      21.0     6   160   110  3.90
    #> 2 Mazda RX4 Wag  21.0     6   160   110  3.90
    #> 3 Datsun 710     22.8     4   108    93  3.85
    

    编辑:我已将这些函数放在a package 中,如果有人觉得它们有用的话。

    【讨论】:

    • 这可以通过具有内联代码的降价表来完成吗?所以像r 21这样的单元格在数据框中变成了21,而不是字符r 21
    • 喜欢... | `r 21` | ...?当然可以,但工作量更大。在任何字符列中迭代 glue::glue(使用 .open = '`r', close = '`' 会起作用。
    • @alistaire 感谢您提供read.so 包——它就像一个魅力!
    【解决方案2】:

    我输入了问题,但后来意识到答案很简单。 readr 包中的函数 read_delim 可以轻松处理这个问题:

    library(readr)
    library(dplyr)
    
    object <- 'Table Header | Second Header \n------------- | ------------- \nTable Cell | Cell 2 \nCell 3 | Cell 4'
    data_frame <- read_delim(object, delim = '|')
    
    # A tibble: 3 x 2
      `Table Header ` ` Second Header `
                <chr>             <chr>
    1  -------------     ------------- 
    2     Table Cell            Cell 2 
    3         Cell 3             Cell 4
    

    只需要过滤掉“------”行。等等。

    希望这个解决方案对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2019-09-30
      • 2021-10-05
      • 2015-09-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      相关资源
      最近更新 更多