【问题标题】:R return types of commands and capturing R model summaries in emac's org modeR 返回命令类型并在 emacs org 模式下捕获 R 模型摘要
【发布时间】:2014-03-19 22:09:31
【问题描述】:

当你在 R 中输入命令时说:

>5
[1] 5

它返回以 [1] 开头的整数 5。使用分号时也会发生类似的情况

>c(1,2,3); c(2,3,4)
[1] 1 2 3
[1] 2 3 4

如果将 5 分配给变量,它不会返回任何内容:

>a = 5

我想我将 R 理解为 repl。如果除了变量赋值之外还有其他内容,它会打印出以 [1] 开头的内容

让我困惑的是做这样的事情

>a = c(1,2,3)
>b = c(1,2,3)
>data = as.data.frame(cbind(a,b))
>model = lm(a ~ b, data)
>summary(model)
Call:
lm(formula = a ~ b, data = data)

Residuals:
1 2 3 
0 0 0 
.
.
.

Residual standard error: 0 on 1 degrees of freedom
Multiple R-squared:      1, Adjusted R-squared:      1 
F-statistic:   Inf on 1 and 1 DF,  p-value: < 2.2e-16

我的问题是为什么模型摘要前面没有[1]?除了 emac 的 org 模式来捕获代码块的结果之外,代码块的末尾似乎需要“返回”一些东西(即前面的 [1] )。我读到需要返回一些东西here。我现在的想法是捕获某种 PNG 格式的摘要输出以显示在我的 org 模式块中,但是,我想了解这里发生了什么以及是否有更基本的 hack。还有没有人有任何最佳实践来在 emac 的 org 模式下捕获 R 模型摘要的输出。

谢谢!!!!

更新:

使用下面我想出的 3 个帖子:

#+begin_src R :results 输出 :session R :exports 结果
库(ascii)
选项(asciiType="org")
选项(警告 = -1)
a = c(1,2,3)
b = c(1,2,3)
数据 = as.data.frame(cbind(a,b))
模型 = lm(a ~ b, 数据)
ascii(总结(模型))
#+end_src

【问题讨论】:

    标签: r emacs org-mode


    【解决方案1】:

    我自己也想过这个问题,于是开始调查源代码。

    没有'[1]'的原因是summary(model)返回一个类summaryDefault的对象,它有一个为它定义的方法SummaryDefault.print,当repl将摘要信息打印到终端并以不可见的方式返回 summaryDefault 对象。因此,print.default 不会打印汇总统计信息本身的基础向量,它在括号内提供了这些索引。

    但是,缺少“[1]”并不是组织返回空白结果的原因。

    原因如下:

    当您使用 :returns value 声明 org-mode 代码块时,Org 模式会尝试将代码块中最后一个表达式的值转换为可以格式化为 org 表的内容(即 | 字符为分隔符)。

    利用R的特殊变量.Last.value得到需要转换的值。

    它尝试通过调用 R 函数 write.table 来将此值转换为,写入一个临时文件,然后读取/解析/重新格式化为格式良好的 org 表。

    唉,write.table,当在 SummaryDefault 类的对象上调用时,会生成一个错误,该错误被捕获并默默地不报告,但该临时文件最终为空。

    所以没有什么可以重新格式化为 org 表。

    您今天的选择包括:

    • OK:用:returns output 声明你的代码块。这样做的缺点是它将返回所有输出,并且摘要没有很好地重新格式化为您可能想要的组织表。
    • OK:保留为returns :value,但将块中的最后一个表达式设为capture.output(summary(model))。输出将是一个单列表,每行输出一行。
    • 更好:保留为returns :value,但使最后一个表达式为unclass(summary(model))。然后将打印矢量。添加:rownames yes,我们看起来很漂亮。
    • 更好:将其保留为 returns :value,但使用 t(summary(model)) 同时取消对值的分类并将其格式化为宽。
    • 最好:将其保留为 returns :value,但使用 t(t(summary(model))) 同时取消对值的分类并保持其格式化。

    毕竟,期望 org 能够神奇地将任何 R 数据结构转换为 data.frame 之类的东西,然后从那里转换为 org 表,这毕竟是遥不可及的。我想 org magic 可以捕获错误并尝试其他方法,例如在它试图强制转换为表格的对象上调用 t(t(.))。或as(.,data.frame)。我不确定这是否在组织“精神”中。我想知道...

    在任何情况下,如果 org 模式会引发错误,例如“Erhm,我如何将 summaryDefault 对象转换为表格”,那将是一件好事。

    还是?

    【讨论】:

      【解决方案2】:

      在 R 中有一个 read-eval-print 循环。但是,有时,如果 print 方法“不可见”地返回值,则该方法不会得到任何东西,尽管这里不是这种情况。此外,在summary 方法(通用)的情况下,通常有特定的print 方法将与通用摘要函数相关联。然后这些打印函数进行干预,并可能在控制台上打印一些被认为更容易被人眼理解的内容,而不是嵌套列表对象实际上是返回值。 (所以print.summary.lm 函数使用cat,它通过副作用起作用并且没有值,以“打印”到控制台,然后返回值......不可见。)在简单的情况下:

      a = 5
      

      您可以测试返回的内容:

      b <- (a = 5)
      b
      [1] 5
      

      所以返回的是赋值的 RHS 上的计算表达式。

      > d = 6
      > e <- (b=d)
      > e
      [1] 6
      

      如果您输入methods(print),您将看到有一个print.summary.lm* 函数调度并处理输出到控制台的任务,但控制台上显示的内容与您在str(summary(model)) 中看到的不同。 (尾部的星号表示如果您只输入函数名称,该函数将不会打印到控制台,但您可以使用 stats:::print.summary.lm 将其打印。)您也可以查看:

      ?`<-`
      ?assign
      

      对于问题的 Emacs 部分,我真的无能为力。您可能希望使用sinkcapture.output 来恢复和存储与控制台输出相同的文本。

      > cap <- capture.output(summary(model))
      > print(cap)
       [1] ""                                                              
       [2] "Call:"                                                         
       [3] "lm(formula = a ~ b, data = data)"                              
       [4] ""                                                              
       [5] "Residuals:"                                                    
       [6] "1 2 3 "                                                        
       [7] "0 0 0 "                                                        
       [8] ""                                                              
       [9] "Coefficients:"                                                 
      [10] "            Estimate Std. Error t value Pr(>|t|)    "          
      [11] "(Intercept)        0          0      NA       NA    "          
      [12] "b                  1          0     Inf   <2e-16 ***"          
      [13] "---"                                                           
      [14] "Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1"
      [15] ""                                                              
      [16] "Residual standard error: 0 on 1 degrees of freedom"            
      [17] "Multiple R-squared:      1,\tAdjusted R-squared:      1 "      
      [18] "F-statistic:   Inf on 1 and 1 DF,  p-value: < 2.2e-16"         
      [19] ""                                                        
      

      【讨论】:

        【解决方案3】:

        [1][2] 等)用于显示向量的值。它指的是该行中显示的最左侧值的索引。 R 中没有标量,这就是为什么您会看到[1],即使您将单个值分配给变量。另一方面,如果您将某些内容打印到标准输出(例如,使用cat),那将不是函数调用返回的值(cat 的结果是“不可见”NULL)而是一个侧面影响。因此,没有[1]

        为了将 R 与 org-mode 一起使用,您需要确定在执行代码块后您希望在文档中包含什么:最后一个值、输出或您编码生成的图像。它由:results header 参数控制:

        #+begin_src R :results value
          a <- 5
        #+end_src
        

        更多详情请查看R Source Code Blocks in Org Mode

        【讨论】:

          猜你喜欢
          • 2016-12-16
          • 1970-01-01
          • 1970-01-01
          • 2015-12-25
          • 2018-10-04
          • 2019-09-21
          • 2021-02-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多