为了正确输出\Sexpr,编写R/Sweave程序

7
我在为Sweave编写R程序时遇到了一些问题,与#rstats Twitter小组经常指向这里,所以我想把这个问题放在SO群众中。我是一名分析师而不是程序员,所以请轻松对待我的第一个帖子。
问题如下:我正在使用R和Sweave起草一份调查报告,并希望使用\Sexpr{}在同一行中报告边际回报率。例如,而不是说:
只有14%的受访者表示“X”。
我想这样写报告:
只有\Sexpr{p.mean(variable)}$\%$的受访者表示“X”。
问题在于,Sweave将\Sexpr{}表达式的结果转换为字符字符串,这意味着R中表达式的输出和出现在我的文档中的输出是不同的。例如,上面我使用了'p.mean'函数:
p.mean<- function (x) {options(digits=1)  
mmm<-weighted.mean(x, weight=weight, na.rm=T)  
print(100*mmm)  
}
在 R 中,输出看起来像这样:
p.mean(variable)
>14

但是当我使用\Sexpr{p.mean(variable)}时,我的文档中会得到一个未舍入的字符字符串(在这种情况下为:13.5857142857143)。我尝试在全局环境中、函数本身以及各种命令中将函数的输出限制为digits=1,但它似乎只包含R打印的内容,而不是表达式的字符转换结果,最终在LaTeX文件中打印。

as.character(p.mean(variable))  
>[1] 14  
>[1] "13.5857142857143"  

有没有人知道我可以通过重新编程R函数或在Sweave或\Sexpr {}中设置来限制LaTeX文件中打印的数字位数?

5个回答

4

@KennyTM明白了。@David,你应该避免使用options(digits = 1),因为它会影响到所有的计算(之后每个输出中都会抑制小数)。所以在应用weighted.mean()后使用round()函数。就像这样:

\Sexpr{round(p.mean(x))}

不要使用print(),而是使用return()。这是因为:

> set.seed(1234)
> x <- rnorm(100)
> foo <- function(x) {
   res <- mean(x) + 5
   print(res)
}
> foo(x)
[1] 5
> foo(x) + 10
[1] 5
[1] 15

使用return()或者直接在最后一行输入结果变量:

> bar <- function(x) {
   res <- mean(x) + 5
   return(res)
}
> bar(x) + 10
[1] 15

因此,请重新编写您的函数,并确保使用as.character()…您已经拥有了所有要素,现在只需将其全部组合起来。
附言:
我不确定您的函数如何工作……我从未在我的分析中使用过加权平均值。最让我困惑的是weight=weight。是否可以在函数中再添加一个参数?坦白地说,我仍然对于您的函数能够给出正确的结果感到惊讶……可能是因为您在函数定义之前定义了weight变量。[编辑]如果您没有预先定义weight函数,那么您的函数将无法得到加权平均值,而只能得到“普通”平均值!
希望这篇文章对您有所帮助!
此致敬礼, Aleksandar

谢谢,Aleksandar。我已经重写了这个函数,像这样:p.mean<- function (x) {
mmm<-weighted.mean(x, weight=weight, na.rm=T)
return(round(100*mmm))
} 我预先指定了权重变量,因为我试图尽量减少编程时间。由于我处理的所有数据集都将其权重变量标记为“weight”,这使得我的编写效率略微提高了一点。
- deoksu

3
尝试使用“format”:
options(digits=1)

接着:

\Sexpr{format(p.mean(variable))}

您可以使用'nsmall'参数:
您还可以使用“nsmall”参数:
options(digits=3)
...
\Sexpr{format(sqrt(2)-0.41,nsmall=2)}

如果您熟悉C语言,还可以尝试使用“sprintf”。


2
as.character(round(p.mean(variable)))

?


谢谢!我将我的函数重写为:
p.mean <- function(x) { mmm <- weighted.mean(x, weight = weight, na.rm = T) return(round(100 * mmm)) }
现在完美运行。
- deoksu

1

sprintf() 函数非常适合格式化数字输出。


0

siunitx 包也可以用于在 Sweave 中格式化数字。

Sweave 代码

以下脚本展示了如何使用它来格式化数字,语法适用于 Sweave。在导言部分,您可以设置默认的格式,例如:

\sisetup{
round-mode = figures,
round-precision = 3
}

然后在命令中覆盖它 \Sexpr{num(pi,round_precision=2)}

\documentclass[a4paper]{article}
\usepackage{siunitx}
\usepackage{Sweave}
\title{siunitx}

\sisetup{
round-mode = figures,
round-precision = 3
}
\begin{document}

\maketitle
<<sanitize_number,echo=FALSE>>=
num <- function(x,round_precision=NULL)
{
  if (is.null(round_precision)) {
    return(sprintf("\\\\num{%s}", x))
  } else {
    return(sprintf("\\\\num[round-precision=%s]{%s}",round_precision, x))
  }
}
@
Examples :\\
round\_precision= 2 gives : \Sexpr{num(pi,round_precision=2)} \\
round\_precision= 4 gives : \Sexpr{num(pi,round_precision=4)}\\
Default formatting gives : \Sexpr{num(pi)}
\end{document}

enter image description here

knitr 代码

在 knitr 中,默认情况下,当设置选项 options(digits = 2) 后,\Sexpr 中的数字会被四舍五入。但如果您想在不同的地方进行不同的舍入,则可以使用以下代码,需要进行适当的调整,因为在 knitr 中不需要双重转义反斜杠。

num <- function(x,round_precision=NULL)
{
  if (is.null(round_precision)) {
    return(sprintf("\\num{%s}", x))
  } else {
    return(sprintf("\\num[round-precision=%s]{%s}",round_precision, x))
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接