我想通过数据生成下面这样的用 ASCII 表达的条形图:

PCA                 ■■■■■■■■■■■■■■ 14
Regression          ■■■■■■■■■■■■ 12
Cluster Analysis    ■■■■■■■■■ 9
Bayesian            ■■■■■■ 6
Post-hoc test       ■ 1
Non-parametric Test ■ 1

不知道有没有哪个 R 包可以实现?最好还能生成其他的简单图形。

我问了 ChatGPT,回答说是 ascii 包就可以,还像模像样给了其中几个函数,以及包的引用条目。我试了发现,这包是存在的,但它给的作图函数都不存在,并且作者也不对。我甚至看了包的早期版本,也完全对不上号。ChatGPT 伪造参考文献是众所周知,但伪造 R 包还是头一次遇见。

一个著名例子是 skimr,可以画线图和直方图,在汇总表格中以 sparkline 的形式呈现。

在有图形设备的前提下,用文本展现图形元素是一个看起来酷炫但不那么可靠的做法,受到字体和有效分辨率的影响,只能展示比较简单的大致趋势。

    fenguoerbian 正是我想要的。完美。感谢!

     txtplot::txtbarchart(as.factor(mtcars$carb), pch = "■")
       +----+-----------------+------------------+-----------------+------------------+-----------------+----+
       |                      ■                                    ■                                         |
    30 +                      ■                                    ■                                         +
       |                      ■                                    ■                                         |
       |                      ■                                    ■                                         |
    25 +                      ■                                    ■                                         +
       |                      ■                                    ■                                         |
       |    ■                 ■                                    ■                                         |
       |    ■                 ■                                    ■                                         |
    20 +    ■                 ■                                    ■                                         +
       |    ■                 ■                                    ■                                         |
       |    ■                 ■                                    ■                                         |
    15 +    ■                 ■                                    ■                                         +
       |    ■                 ■                                    ■                                         |
       |    ■                 ■                                    ■                                         |
    10 +    ■                 ■                                    ■                                         +
       |    ■                 ■                  ■                 ■                                         |
       |    ■                 ■                  ■                 ■                                         |
       |    ■                 ■                  ■                 ■                                         |
     5 +    ■                 ■                  ■                 ■                                         +
       |    ■                 ■                  ■                 ■                  ■                 ■    |
       |    ■                 ■                  ■                 ■                  ■                 ■    |
     0 +    ■                 ■                  ■                 ■                  ■                 ■    +
       +----+-----------------+------------------+-----------------+------------------+-----------------+----+
            1                 2                  3                 4                  5                 6     
    Legend: 1=1, 2=2, 3=3, 4=4, 5=6, 6=8

    chuxinyuan 对,我就是受到茎叶图的启发,才想着怎么用字符表示图的。

    nan.xiao 这个包不错!谢谢推荐。确实不能精准表达,只适用于特殊场合,比如上课的时候增加一点课堂效果,免得学生睡着了。

    > skimr::skim(mtcars)
    ── Data Summary ────────────────────────
                               Values
    Name                       mtcars
    Number of rows             32    
    Number of columns          11    
    _______________________          
    Column type frequency:           
      numeric                  11    
    ________________________         
    Group variables            None  
    
    ── Variable type: numeric ───────────────────────────────────────────────────────────────────────────────────────────────────────────
       skim_variable n_missing complete_rate    mean      sd    p0    p25    p50    p75   p100 hist 
     1 mpg                   0             1  20.1     6.03  10.4   15.4   19.2   22.8   33.9  ▃▇▅▁▂
     2 cyl                   0             1   6.19    1.79   4      4      6      8      8    ▆▁▃▁▇
     3 disp                  0             1 231.    124.    71.1  121.   196.   326    472    ▇▃▃▃▂
     4 hp                    0             1 147.     68.6   52     96.5  123    180    335    ▇▇▆▃▁
     5 drat                  0             1   3.60    0.535  2.76   3.08   3.70   3.92   4.93 ▇▃▇▅▁
     6 wt                    0             1   3.22    0.978  1.51   2.58   3.32   3.61   5.42 ▃▃▇▁▂
     7 qsec                  0             1  17.8     1.79  14.5   16.9   17.7   18.9   22.9  ▃▇▇▂▁
     8 vs                    0             1   0.438   0.504  0      0      0      1      1    ▇▁▁▁▆
     9 am                    0             1   0.406   0.499  0      0      0      1      1    ▇▁▁▁▆
    10 gear                  0             1   3.69    0.738  3      3      4      4      5    ▇▁▆▁▂
    11 carb                  0             1   2.81    1.62   1      2      2      4      8    ▇▂▅▁▁

    已有的方案没法绘制躺平的条形图,也不支持二维联表。所以我自己写了个函数,放在了 fecitr 包里:

    默认风格:

    remotes::install_github('pzhaonet/fecitr')
    library(fecitr)
    x <- txt_bar(value = VADeaths[1, ], label = colnames(VADeaths))
    #> +------------------------------+
    #> |   Rural Male ######## 11.7   |
    #> | Rural Female ###### 8.7      |
    #> |   Urban Male ########## 15.4 |
    #> | Urban Female ##### 8.4       |
    #> +------------------------------+

    定制最小单位和表达字符:

    x <- txt_bar(value = VADeaths[1, ], label = colnames(VADeaths), 
                 quantum = 1, pch = '■')
    #> +-----------------------------------+
    #> |   Rural Male ■■■■■■■■■■■■ 11.7    |
    #> | Rural Female ■■■■■■■■■ 8.7        |
    #> |   Urban Male ■■■■■■■■■■■■■■■ 15.4 |
    #> | Urban Female ■■■■■■■■ 8.4         |
    #> +-----------------------------------+

    2 x 2 表:

    x <- txt_bar(value = VADeaths[1, ], label = c('Rural', '', 'Urban', ''), 
                 quantum = 1, pch = c('■', '□'), legend = c('Male', 'Female'))
    #> +----------------------------+
    #> | Rural ■■■■■■■■■■■■ 11.7    |
    #> |       □□□□□□□□□ 8.7        |
    #> | Urban ■■■■■■■■■■■■■■■ 15.4 |
    #> |       □□□□□□□□ 8.4         |
    #> +----------------------------+
    #> 
    #> Legend: ■ Male;□ Female

    4 x 5 表:

    vt <- t(VADeaths)
    label <- rep(colnames(vt), each = nrow(vt))
    label[duplicated(label)] <- ''
    x <- txt_bar(value = as.vector(vt), label = label, 
                 quantum = 2, pch = c('■', '□', '+', '='), legend = row.names(vt))
    #> +-------------------------------------------------+
    #> | 50-54 ■■■■■■ 11.7                               |
    #> |       □□□□ 8.7                                  |
    #> |       ++++++++ 15.4                             |
    #> |       ==== 8.4                                  |
    #> | 55-59 ■■■■■■■■■ 18.1                            |
    #> |       □□□□□□ 11.7                               |
    #> |       ++++++++++++ 24.3                         |
    #> |       ======= 13.6                              |
    #> | 60-64 ■■■■■■■■■■■■■ 26.9                        |
    #> |       □□□□□□□□□□ 20.3                           |
    #> |       ++++++++++++++++++ 37                     |
    #> |       ========== 19.3                           |
    #> | 65-69 ■■■■■■■■■■■■■■■■■■■■ 41                   |
    #> |       □□□□□□□□□□□□□□□ 30.9                      |
    #> |       +++++++++++++++++++++++++++ 54.6          |
    #> |       ================== 35.1                   |
    #> | 70-74 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 66      |
    #> |       □□□□□□□□□□□□□□□□□□□□□□□□□□□ 54.3          |
    #> |       ++++++++++++++++++++++++++++++++++++ 71.1 |
    #> |       ========================= 50              |
    #> +-------------------------------------------------+
    #> 
    #> Legend: ■ Rural Male;□ Rural Female;+ Urban Male;= Urban Female

    直方图:

    xhist <- hist(iris$Sepal.Length, plot = FALSE)
    label <- paste(xhist$breaks[1:(length(xhist$breaks)-1)], '-', xhist$breaks[2:length(xhist$breaks)])
    txt_bar(xhist$counts, label, pch = '哈', add_box = FALSE)
    #> 4 - 4.5 哈哈 5
    #> 4.5 - 5 哈哈哈哈哈哈哈哈哈 27
    #> 5 - 5.5 哈哈哈哈哈哈哈哈哈 27
    #> 5.5 - 6 哈哈哈哈哈哈哈哈哈哈 30
    #> 6 - 6.5 哈哈哈哈哈哈哈哈哈哈 31
    #> 6.5 - 7 哈哈哈哈哈哈 18
    #> 7 - 7.5 哈哈 6
    #> 7.5 - 8 哈哈 6